How to execute raw SQL in Flask-SQLAlchemy app
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Flask-SQLAlchemy lets you use the ORM for most queries, but sometimes raw SQL is the better tool. That happens when you need vendor-specific features, a query that is awkward in ORM form, or a hand-tuned statement for reporting or migration work. The main rule is to execute raw SQL through SQLAlchemy’s session or connection APIs and keep parameter binding explicit.
Use text() with db.session.execute
The standard pattern is to wrap the SQL string in sqlalchemy.text and pass parameters separately.
This is the basic answer for raw SELECT execution in a Flask-SQLAlchemy application.
Use Bound Parameters, Not String Interpolation
Even when the SQL itself is handwritten, values should still be passed as parameters.
Bad pattern:
Good pattern:
This matters for both security and correctness. Parameters handle quoting, escaping, and data typing more reliably than string formatting.
Modifying Data Requires a Commit
If the SQL changes the database, the session still needs to commit the transaction.
This works for INSERT, UPDATE, and DELETE just as it would for ORM-managed changes.
Use Result Mappings When You Want Dictionary-Like Access
Depending on the SQLAlchemy version and result style, rows can behave like tuple-like objects. If you want mapping-style access by column name, use .mappings().
This is often clearer for ad hoc reporting code or when the column list is dynamic.
Use a Connection for Lower-Level Work
Session execution is the normal application path, but lower-level work can also use an engine connection directly.
This style is useful when you want direct connection semantics or are working outside normal ORM transaction flows.
Raw SQL and ORM Can Coexist
Using raw SQL does not mean abandoning Flask-SQLAlchemy. The practical balance is usually:
- ORM for common CRUD and model-centric queries
- raw SQL for specialized or database-specific work
That balance keeps most of the application readable while still letting you drop lower when the ORM is not the best fit.
Keep Raw SQL Local and Intentional
Raw SQL becomes hard to maintain if it spreads everywhere. A good pattern is to keep it:
- near the repository or service layer that owns the query
- parameterized and clearly named
- isolated from presentation code
That way the application still has one obvious place to inspect when a particular hand-written query changes.
Common Pitfalls
- Building raw SQL with string interpolation instead of bound parameters.
- Forgetting to commit after
INSERT,UPDATE, orDELETE. - Mixing connection-level and session-level transaction handling without understanding the boundaries.
- Using raw SQL everywhere when the ORM would be simpler for ordinary queries.
- Assuming row access style will always look the same without checking whether
.mappings()is needed.
Summary
- In Flask-SQLAlchemy, raw SQL is usually executed through
db.session.execute(text(...), params). - Always bind parameters instead of formatting values directly into SQL strings.
- Data-changing statements still need
db.session.commit(). - Use
.mappings()when dictionary-like row access is clearer. - Raw SQL is a useful tool, but it works best when kept intentional and localized.
Related reading
- How to export a mysql database using Command Prompt?
- How to export an existing dynamo table schema to json?
- How to export an existing dynamo table schema to json?
- How to export and import a .sql file from command line with options?
- How to exit from Python without traceback?
- How to exit the entire application from a Python thread?
- How to export database from Amazon RDS MySQL instance to local instance?
- How to export database from Amazon RDS MySQL instance to local instance?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.