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.