DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk4 min

A Practical Guide to Raw SQL in Python with SQLAlchemy 2.x

SQLAlchemy 2.x lets Python developers write handwritten SQL while keeping values bound separately. See when to use text(), exec_driver_sql(), Core, or ORM queries.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can write SQL by hand in Python without giving up parameter safety or SQLAlchemy’s connection and result handling. In SQLAlchemy 2.x, use text() with Connection.execute() for most handwritten statements, and pass values separately as bound parameters. Use exec_driver_sql() only when you specifically need to send driver-level SQL; use Core expressions or ORM queries when their higher-level construction fits the job.

Run handwritten SQL with SQLAlchemy 2.x

This example uses SQLAlchemy’s documented textual SQL interface. The statement contains a named parameter, while the value is supplied separately to execute():

from sqlalchemy import create_engine, text

engine = create_engine("sqlite:///app.db")

with engine.connect() as conn:
    result = conn.execute(
        text("SELECT x, y FROM some_table WHERE y > :y"),
        {"y": 2},
    )
    for row in result.mappings():
        print(row["x"], row["y"])

The connection context manager closes the connection when the block ends. text() makes the SQL string a SQLAlchemy textual statement, and result.mappings() lets you access returned rows by column name. The example follows the SQLAlchemy 2.0 tutorial.

Do not put quotes around :y or build a query string containing the value yourself. The SQLAlchemy dialect and database driver handle binding the separate value using the conventions appropriate to that backend.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep values separate from SQL

Never insert untrusted values into SQL with an f-string, concatenation, percent formatting, or another interpolation method. For example, do not form a statement such as f"... WHERE name = '{name}'". Pass the value through the API’s parameter mechanism instead:

stmt = text("SELECT id FROM users WHERE name = :name")

with engine.connect() as conn:
    result = conn.execute(stmt, {"name": name})

SQLAlchemy’s textual SQL guidance says not to stringify Python values into statements and advises: “Always use bound parameters.” The SQLAlchemy FAQ likewise recommends bound parameters for programmatically executed non-DDL statements. Binding is a safety rule for values; it does not turn arbitrary SQL structure into safe input.

Values are not identifiers or SQL fragments

A parameter represents a value, such as a name or numeric threshold. It does not stand in for a table name, column name, sort direction, or arbitrary SQL syntax. If those parts must vary, select them from a deliberate allowlist or use an identifier-composition facility supported by the specific backend or library. Do not treat a bound-value placeholder as a general-purpose way to inject SQL structure.

Choose between text(), driver SQL, and expressions

Approach SQL control SQLAlchemy integration Driver dependence Best fit
text() with Connection.execute() You write the SQL statement directly. Uses SQLAlchemy’s textual statement and parameter handling, with SQLAlchemy-level typing and result behavior. Dialect translates parameter handling for the configured backend. Handwritten SQL that should remain integrated with SQLAlchemy.
Connection.exec_driver_sql() You pass a SQL string directly to the underlying DBAPI driver. Bypasses SQLAlchemy’s text() statement abstraction; execution follows driver-level conventions. More directly dependent on the DBAPI driver, including its parameter style. Cases that specifically require driver-direct SQL behavior.
Core expressions or ORM queries You construct the query from SQLAlchemy expression or ORM constructs rather than writing the whole statement as text. Provides a higher level of query construction; ORM statements use the mapped model. SQLAlchemy handles dialect translation for the configured backend. Queries built programmatically or work that benefits from expression and ORM abstractions.

SQLAlchemy describes textual SQL as an exception in ordinary day-to-day use, not as an unsupported feature. Core and ORM constructs provide more abstraction; they are useful when query composition and mapped entities matter. The Core overview and ORM Querying Guide document those alternatives.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When text() is the practical default

Choose text() when the statement is clearest as SQL you write yourself but you still want SQLAlchemy’s parameter and result integration. This is often a straightforward fit for a fixed query with a few variable values.

When exec_driver_sql() is warranted

Choose exec_driver_sql() only when the statement needs to go straight to the DBAPI driver. Unlike text(), its SQL string and parameter conventions are driver-specific. Consult the configured driver’s documentation for its placeholder style and calling conventions. The distinction is described in SQLAlchemy’s Engines and Connections documentation.

When Core or the ORM is a better fit

When application logic assembles a query from optional conditions or other changing pieces, Core expressions can provide structured construction. For ORM queries in SQLAlchemy 2.x, build a select() statement and execute it with Session.execute(). Handwritten SQL and ORM querying are neighboring options within SQLAlchemy, not mutually exclusive camps.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Account for the database and driver

SQLAlchemy supports dialects for several major database families, but using a dialect also requires an appropriate DB-API implementation. The example above explicitly targets SQLite with the sqlite:///app.db connection URL; it does not imply that every backend uses the same SQL placeholder syntax or driver behavior. With text(), use SQLAlchemy’s named parameter form in the statement and provide a separate mapping of values. With exec_driver_sql(), follow the underlying driver’s own parameter convention. SQLAlchemy lists supported dialect families and the DB-API requirement on its Features page.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not inline values for execution or debugging

SQLAlchemy’s literal_binds option can render values inline in some SQL output, but it is not a substitute for binding values during execution. The FAQ presents inline rendering mainly as a logging or debugging aid and notes datatype limitations; it warns against using it with untrusted input. Keep execution parameters separate rather than converting them into SQL text.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.