PostgreSQL persistence for air.AirModel.
Air keeps model definitions and the async CRUD API in core. AirPostgres provides the PostgreSQL-specific pieces: asyncpg pooling, SQL generation, transactions, and table creation.
- GitHub | PyPI | Documentation
- Created by Audrey M. Roy Greenfeld and Daniel Roy Greenfeld | GitHub @audreyfeldroy | PyPI @audreyfeldroy
- MIT License
- Async CRUD and backend-neutral query lookups for
AirModelclasses - Asyncpg pool lifecycle and transaction management
- Idempotent table creation with non-destructive column additions
- Typed support for Python 3.13 and newer
uv add AirPostgresfrom contextlib import asynccontextmanager
import air
from airpostgres import AirPostgres
class Note(air.AirModel):
id: int | None = air.AirField(default=None, primary_key=True)
body: str
database = AirPostgres()
@asynccontextmanager
async def lifespan(app):
async with database.lifespan("postgresql://localhost/example")(app):
await database.create_tables()
yield
app = air.Air(lifespan=lifespan)Application models import only from air. Replacing AirPostgres with another
backend, such as AirD1, does not change those model definitions.
Full documentation is available on GitHub Pages.
See CONTRIBUTING.md for development setup, testing, and documentation instructions.
AirPostgres was created in 2026 by Audrey M. Roy Greenfeld and Daniel Roy Greenfeld.
Built with Cookiecutter and the audreyfeldroy/cookiecutter-pypackage project template.