Alembic Utils
Alembic Utils is an extension for SQLAlchemy and Alembic, enabling the migration and management of PostgreSQL-specific database entities such as functions, views, materialized views, triggers, and policies. It helps integrate DDL (Data Definition Language) for these objects into the standard Alembic migration workflow. The current version is 0.8.8, with an active but moderate release cadence.
Warnings
- breaking `PGText` was removed in version `0.8.0`. Users who previously used `PGText` for defining functions or views must migrate their definitions to `PGFunction` or `PGView` respectively. This change provides more specific and structured interfaces for each entity type.
- breaking The `PGFunction` constructor signature changed in version `0.6.0`, making the `returns` argument mandatory. Migrations using `PGFunction` from older versions will fail if `returns` is not provided.
- gotcha Alembic integration for change detection and synchronization varies by version. For Alembic >= 1.10.0 and Alembic-Utils >= 0.8.0, the preferred method to automatically manage entities defined in your application models is `op.sync_alembic_utils()`, typically called in `env.py`. For older versions, `add_alembic_utils_meta(op)` was used in `env.py`.
- gotcha Alembic Utils is primarily designed for PostgreSQL. While some concepts might apply to other SQL dialects, the specific entity classes (e.g., `PGView`, `PGFunction`) and their underlying DDL generation are tailored to PostgreSQL syntax and features. Attempting to use these with other databases may lead to syntax errors or unexpected behavior.
Install
-
pip install alembic-utils
Imports
- PGView
from alembic_utils.pg_view import PGView
- PGFunction
from alembic_utils.pg_function import PGFunction
- PGMaterializedView
from alembic_utils.pg_materialized_view import PGMaterializedView
- PGTrigger
from alembic_utils.pg_trigger import PGTrigger
- PGPolicy
from alembic_utils.pg_policy import PGPolicy
- add_alembic_utils_meta
from alembic_utils.utils import add_alembic_utils_meta
Quickstart
import sys
from alembic_utils.pg_view import PGView
from alembic_utils.pg_function import PGFunction
# Mock op object for demonstration purposes to show API usage.
# In a real Alembic migration, `op` is provided by Alembic.
class MockOp:
def execute(self, statement):
print(f"Executing DDL: {statement}")
def create_entity(self, entity):
print(f"Creating entity: {entity.entity_name}")
print(f" Definition: {entity.to_sql_statement()}")
def drop_entity(self, entity):
print(f"Dropping entity: {entity.entity_name}")
print(f" Definition: {entity.to_sql_drop_statement()}")
def sync_alembic_utils(self):
print("Synchronizing Alembic-Utils entities (mocked).")
op = MockOp()
# Define a PostgreSQL view
my_view = PGView(
schema="public",
signature="my_first_view",
definition="SELECT id, name FROM users WHERE active = TRUE;"
)
# Define a PostgreSQL function
my_function = PGFunction(
schema="public",
signature="my_first_function(a integer, b integer)",
definition="RETURNS integer LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN RETURN a + b; END; $$",
returns="integer" # Required since 0.6.0
)
# Simulate usage in an Alembic migration's upgrade() function
print("--- Simulating 'upgrade' phase ---")
op.create_entity(my_view)
op.create_entity(my_function)
# For Alembic >= 1.10.0 and Alembic-Utils >= 0.8.0, use this in env.py
# to automatically discover and manage entities defined in your model.
# If you define entities directly in migration scripts, this might not be needed.
op.sync_alembic_utils()
print("\n--- Simulating 'downgrade' phase ---")
# Entities should be dropped in reverse order of creation if dependencies exist
op.drop_entity(my_function)
op.drop_entity(my_view)