Skip to content

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).