iron_sql generates typed async PostgreSQL clients and runtime helpers from schemas and SQL queries
Project description
iron_sql
iron_sql is a typed SQL code generator and async runtime for PostgreSQL. Write SQL where you use it, run generate_sql_module, and get a module with typed dataclasses, query helpers, and pooled connections without hand-written boilerplate.
Installation
pip install iron-sql # runtime only (psycopg + psycopg-pool + pydantic)
pip install iron-sql[codegen] # + inflection for code generation
The sqlc binary is bundled automatically via the sqlc Python package.
Key Features
- Query discovery.
generate_sql_modulescans your codebase for calls like<module>_sql("SELECT ..."), runssqlcfor type analysis, and emits a typed module. - Strong typing. Generated dataclasses and method signatures flow through your IDE and type checker.
- Async runtime. Built on
psycopgv3 with pooled connections, context-based connection reuse, and transaction helpers. - Streaming.
query_stream()uses server-side cursors for memory-efficient iteration over large result sets. - Safe by default. Helper methods enforce expected row counts instead of returning silent
None.
Package Layout
runtime.py-- asyncConnectionPool, row helpers (get_one_row,typed_scalar_row), JSON validation decorators.codegen/generator.py-- query discovery, type resolution, module rendering.codegen/sqlc.py-- wraps thesqlcCLI and models its JSON output.codegen/util.py-- shared codegen utilities (indent_block,write_if_changed).
Getting Started
- Add a schema file. A Postgres DDL dump, e.g.
db/schema.sql. - Write queries where they live. Import the future helper and use SQL literals inline:
from myapp.db.mydb import mydb_sql user = await mydb_sql( "SELECT id, username, email, created_at FROM users WHERE id = @user_id" ).query_single_row(user_id=uid)
Named parameters use@param(required) or@param?(optional, expands tosqlc.narg). Positional$1works too. - Generate the client module.
from pathlib import Path from iron_sql.codegen import generate_sql_module generate_sql_module( schema_path=Path("schema.sql"), module_full_name="myapp.db.mydb", dsn_expr="myapp.config:DSN", src_path=Path("."), )
This writesmyapp/db/mydb.pycontaining:- a connection pool singleton,
*_connection()and*_transaction()context managers,*_listen_session(channel)and*_notify(channel, payload="")helpers,- dataclasses for multi-column results (deduplicated by table),
StrEnumclasses for PostgreSQL enums,- a query class per statement with typed methods,
- overloads for the
*_sql()helper so editors infer return types.
Customization
- Type overrides.
type_overrides={"custom_type": "int"}maps database type names to Python type strings. - JSON model overrides.
json_model_overrides={"users.metadata": "myapp.models:UserMeta"}adds Pydantic validation for JSON/JSONB columns. - Naming conventions. Supply
to_pascal_fnandto_snake_fncallables to control generated names. - Connection settings.
dsn_exprandpool_options_exprare written verbatim into the generated module; point them at config variables, env var lookups, or function calls. - Debug artifacts. Pass
debug_pathto save sqlc inputs and outputs for inspection.
Runtime Highlights
ConnectionPoolopens lazily and reopens afterclose(), withContextVar-based connection reuse for nested contexts.*_listen_session()uses a dedicated pooled connection and doesn't reuseContextVartransaction connections.query_single_row()raisesNoRowsError;query_optional_row()returnsNone. Both raiseTooManyRowsErroron 2+ rows.query_stream()returns an async context manager yielding anAsyncGenerator; uses server-side cursors with automatic transaction management.- JSONB params are sent with
psycopg.types.json.Jsonb; JSON withpsycopg.types.json.Json. Scalar row factories validate types at runtime. json_validateddecorator applies Pydantic model validation to dataclass fields on construction.
Example
The example/ directory contains a complete working setup: a PostgreSQL schema, generation script with testcontainers, and sample query definitions. See example/generate.py for the codegen call and example/myapp/main.py for query usage.
Validation and Troubleshooting
- Errors identify the file and line where the problematic statement lives.
- Unknown SQL types map to
objectand emitUnknownSQLTypeWarning(promotable to error withwarnings.filterwarnings). - Statements with the same SQL but conflicting
row_typevalues are rejected at generation time.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iron_sql-0.5.3.tar.gz.
File metadata
- Download URL: iron_sql-0.5.3.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abee2207fea3eba944ed7571be4207e7f45b7f4eda6a887046b37a98e9c2a508
|
|
| MD5 |
47c5a2c6d75b360c3285e02e7a87d99a
|
|
| BLAKE2b-256 |
d1271869c9bc87a405a06b07047a6ea286634d624510aec4be01668c0d0503a8
|
File details
Details for the file iron_sql-0.5.3-py3-none-any.whl.
File metadata
- Download URL: iron_sql-0.5.3-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc0cb4717db7ef289c7755d35306d5abb45d65761bcfada6ab2fe044112e5ba9
|
|
| MD5 |
eaa6a82344cfe77aebdd8210e0a28b28
|
|
| BLAKE2b-256 |
9d84c24ebbe3126bf66ffc83fe3a1c11992e83c1dd991e4d64014add89a8140f
|