Playground

playground/models.py is an importable example of the supported, plugin-free API. Models use SQLAlchemy’s ordinary sqlalchemy.orm.DeclarativeBase; codegen_database contributes metadata objects and Alembic integration rather than replacing ORM mapping.

Models and types

User and Student demonstrate explicit primary keys, a relationship, a schema-qualified foreign key, a check constraint, and an index. Student uses codegen_database.TextEnum with the Python EnrollmentStatus enum. Other custom types are available from codegen_database.types; some require a corresponding PostgreSQL extension.

Views

Views support both declarative and imperative styles. ActiveStudent is a plain declarative view, while StudentCount sets ViewOptions(materialized=True). They inherit the same project base as models and are ORM-selectable directly:

from sqlalchemy import select
from playground.models import ActiveStudent, StudentCount

active_query = select(ActiveStudent).order_by(ActiveStudent.name)
counts_query = select(StudentCount)

The declarative shape uses the shared base:

class ActiveStudent(Base):
    __tablename__ = "active_students"
    __table_args__ = {"schema": "public"}
    __query__ = select(...)

imperative_student_names and imperative_student_totals demonstrate the unchanged imperative plain and materialized APIs. Imperative views expose a .table proxy for queries:

from sqlalchemy import select
from playground.models import imperative_student_names

names_query = select(imperative_student_names.table)

Both styles register DDL on application metadata while using detached proxy tables, so Alembic sees views rather than physical tables.

Functions

Functions also support both styles. StudentNamesForUser is a declarative class with a typed PostgreSQL parameter:

class StudentNamesForUser(Base):
    __funcname__ = "student_names_for_user"
    __table_args__ = {"schema": "public"}
    __definition__ = "SELECT ..."
    __options__ = FunctionOptions(
        returns="text",
        parameters=[FunctionParam.input("p_user_id", "integer")],
    )

imperative_active_student_count demonstrates direct CodegenDatabaseFunction(...) construction. Functions do not participate in ORM mapping in either style.

Extensions and RLS

The active codegen_database.ext.chart.ChartExtension registers the portable codegen_database_date_bin PostgreSQL function in the configured utility schema. students_for_current_user demonstrates explicit codegen_database.ext.rls.RLSPolicy registration; the global Alembic hook compares and migrates registered policies without model plugins.

configure_metadata also registers pg_trgm by default. Optional server extensions are intentionally not enabled by the playground. Enable them only when the PostgreSQL server has the required packages:

from codegen_database.ext.pg_cron import (
    CronJob,
    PGCronExtension,
    register_cron_job,
)

codegen_database_config.use(PGCronExtension())
register_cron_job(
    metadata,
    CronJob(
        name="nightly_cleanup",
        schedule="0 2 * * *",
        command="DELETE FROM private.students WHERE false",
    ),
)
from codegen_database.ext.postgis import PostGISExtension

codegen_database_config.use(PostGISExtension(postgis=True))

Migrations

playground/migrations/env.py passes the shared configuration to alembic_hook before metadata configuration, then calls configure_metadata after importing all models, views, functions, and RLS policies. Generate and apply migrations instead of hand-writing a revision:

$ cd playground
$ just revision "initial playground schema"
$ just migrate

The generated migration includes tables, schemas, views, functions, extension metadata, and RLS operations registered on the shared metadata.