Type-safe Python from your SQL
A sqlc plugin that generates modern, fully typed Python database code from plain SQL - models plus async query functions.
Four model types
Generate dataclass, attrs, msgspec, or pydantic models - pick per codegen block.
Four drivers
asyncpg and psycopg for PostgreSQL, plus aiosqlite and sqlite3 for SQLite.
Strictly typed output
Generated code passes pyright strict and ruff, targeting Python 3.12+.
Enums
PostgreSQL enums become enum.StrEnum classes, wired through models and queries.
Type overrides & converters
Swap a column’s Python type, or plug in your own encode/decode functions.
Docstrings
Optional google, numpy, or pep257 docstrings on every generated function.
Used by
Projects running their database layer on generated code:
Using sqlc-gen-better-python in your project?
Open an issue to get
listed here.
From SQL to Python
You write a query, annotated with the name and shape you want:
-- name: GetUser :one
SELECT * FROM users WHERE id = $1;and get a typed function back, with a model built from your schema:
async def get_user(conn: ConnectionLike, *, id_: int) -> models.User | None:
row = await conn.fetchrow(GET_USER, id_)
if row is None:
return None
return models.User(id_=row[0], name=row[1])No ORM, no hand-written row unpacking, and pyright checks every field access.
One schema, four model types
Set model_type and the same table generates whichever flavour your project
already uses - the fields and annotations are identical:
@dataclasses.dataclass()
class User:
id_: int
name: strBuilt to be trusted
Generated code is held to the same standard as hand-written code:
- Type-checked. Every generated file passes pyright in strict mode and ruff.
- Tested against real databases. The suite runs the generated code against live PostgreSQL and SQLite, across every driver and model type.
- Deterministic. Output is byte-identical between runs, and CI fails if a change would silently alter what you get.
Set up in three steps
Point sqlc at the plugin, pick a driver and a model type, and generate:
# sqlc.yaml
version: "2"
plugins:
- name: python
wasm:
url: https://github.com/rayakame/sqlc-gen-better-python/releases/download/v0.6.0/sqlc-gen-better-python.wasm
sha256: 16f5affb502f2ec65ca61f6fc5ddd993449c4a4fc281996c3c9a9bc2e35b1474
sql:
- engine: "postgresql"
queries: "query.sql"
schema: "schema.sql"
codegen:
- out: "app/db"
plugin: python
options:
package: "db"
emit_init_file: true
sql_driver: "asyncpg"sqlc generate