Why rowx¶
rowx is SQLx for Python 3.14+: typesafe raw SQL as a PEP 750 t-string, checked by
rowx check against a live Postgres 18 database, with no ORM. The user guide is how to write and run a
query. The packages page lists the four distributions.
Comparison¶
The rowx row follows the guide and reference. Each other row links to that project's documentation.
| Project | Where the SQL lives | Whether a live database checks it | ORM or not | Whether the project is a Postgres driver | Offline cache versus generated code |
|---|---|---|---|---|---|
| rowx | An inline t-string on query[T] (Queries). |
Yes, for a checked statement. rowx check prepares and describes each checked statement against a live Postgres 18 database. query_unchecked SQL is not described (checker reference). The checker never imports or executes application code (checker guide). |
No. Raw SQL in t-strings (user guide). | Yes. rowx-postgres, on tokio-postgres (packages, driver). |
Described column metadata is not written to a disk cache (checker reference). |
| SQLx | SQL string literals in the query! macro. The repository is transact-rs/sqlx. |
Yes, at compile time. DATABASE_URL must point at a database server with the schema the query string is checked against, unless offline mode is used. |
No. query! maps columns onto an anonymous struct. query_as! maps a row onto a struct you name. |
Yes. Postgres is a PostgreSQL database driver. |
Offline mode stores a .sqlx directory so a later compile can skip the live database. |
| asyncpg | SQL strings passed to connection methods such as execute and fetchrow (usage). |
No. Connection methods run SQL strings at runtime (usage). Those docs do not describe checking the strings against a schema before the program runs. | No. A PostgreSQL protocol library for Python and asyncio. One FAQ entry is whether that library can be used with the SQLAlchemy ORM. | Yes. The introduction describes an implementation of the PostgreSQL server binary protocol. | Neither. The introduction describes a runtime library. It does not describe an offline query cache or generated code. |
| psycopg | SQL strings passed to execute (basic usage). |
No. execute sends SQL at runtime (basic usage). Static typing annotates the Python API and the rows that come back. It does not prepare the SQL against the database schema. |
No. A PostgreSQL database adapter for Python. | Yes. The documentation describes a PostgreSQL database adapter for Python. | Neither. The usage guide describes a runtime adapter. It does not describe an offline query cache or generated code. |
| SQLAlchemy | SQL expression objects and ORM mappings (overview). Raw SQL is a text() or tstring() construct executed by a DBAPI. tstring() accepts a PEP 750 t-string. Those docs do not describe preparing it against a live schema. |
No. Those expressions run through a DBAPI at runtime (overview). The docs do not describe checking them against a live schema before the program runs. | Yes. SQL toolkit and object relational mapper. | A dialect over a DBAPI. It is designed to operate with a DBAPI (Installing a Database API). PostgreSQL options include psycopg and asyncpg (dialect). | Neither. The overview describes a runtime toolkit. It does not describe an offline query cache or generated query functions. |
| sqlc | Schema and queries live in separate SQL files (generate). | sqlc generate parses the SQL files and analyzes them with a built-in engine. A database connection is optional, for enhanced analysis (generate). |
No. It generates code from SQL. The docs do not describe an ORM. | The PostgreSQL tutorial emits code that runs with a separate driver, pgx (tutorial). |
sqlc generate emits the host code the application calls. With managed databases, analysis can also be cached locally (generate). |