Migrations¶
The Alembic bridge. get_metadata() builds a SQLAlchemy MetaData describing all registered Ferro models from the compiled SchemaIR modelset, so Alembic's --autogenerate can diff your models against the live database and emit migration scripts. Assign it to target_metadata in your Alembic env.py (requires the ferro-orm[alembic] extra). See the Schema Migrations guide for the full workflow.
Internal JSON-derivation helpers (_build_sa_table, _map_to_sa_type) are deprecated and scheduled for removal in v0.14.0. Replace internal usages with get_metadata(); see Migrating to v0.12.0.
get_metadata()
¶
Generate a SQLAlchemy MetaData object representing all registered Ferro models. This is intended to be used in alembic's env.py for autogenerate support.
Enum columns are mapped to named sqlalchemy.Enum types so PostgreSQL
autogenerate and DDL compilation succeed (anonymous enums are rejected).
When the field annotation is a Python enum.Enum subclass, the database
type name defaults to the enum class name in lowercase; otherwise the
column name is used as the type name.
For :class:~ferro.base.ForeignKey fields with unique=True (one-to-one
relations), the shadow *_id column is emitted with Column(unique=True)
so Alembic autogenerate includes the matching UNIQUE constraint.
Column nullability: Column.nullable follows :class:~ferro.base.FerroField
/ :class:~ferro.base.ForeignKey nullable when set to a boolean (force
NULL / NOT NULL). The default nullable='infer' uses whether the Python
annotation allows None (after unwrapping Annotated). Shadow *_id
columns infer from the forward relation field's annotation, not from the
synthetic *_id field. Primary key columns are always nullable=False.
Pydantic "required" and JSON-schema defaults do not change inferred nullability.