Complete worked example
python
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, inspect, text
from alembic.migration import MigrationContext
from alembic.operations import Operations
from alembic.autogenerate import produce_migrations
def inspect_example(score):
engine = create_engine("sqlite+pysqlite://", connect_args={"autocommit": False})
try:
original = MetaData()
Table("roles", original, Column("id", Integer, primary_key=True), Column("score", Integer))
original.create_all(engine)
proposed = MetaData()
Table("roles", proposed, Column("id", Integer, primary_key=True),
Column("score", Integer), Column("label", String(30), nullable=True))
with engine.begin() as connection:
connection.execute(text("INSERT INTO roles VALUES (1, :score)"), {"score": score})
context = MigrationContext.configure(connection)
candidate = produce_migrations(context, proposed)
changes = [item.to_diff_tuple()[0] for table in candidate.upgrade_ops.ops for item in table.ops]
# Review this specific additive change; do not blindly run arbitrary candidates.
operation = Operations(context)
operation.add_column("roles", Column("label", String(30), nullable=True))
clean_after = produce_migrations(context, proposed).upgrade_ops.is_empty()
columns = [column["name"] for column in inspect(connection).get_columns("roles")]
return {"candidates": changes, "cleanAfter": clean_after, "columns": columns,
"score": connection.scalar(text("SELECT score FROM roles"))}
finally:
engine.dispose()- Reasoning
- The first comparison produces an add_column candidate. The program then explicitly calls Operations.add_column for that reviewed field and compares again. The final plan is empty, the actual inspected columns include label, and the original score still exists. An empty remaining schema diff is evidence for the compared metadata and comparison settings. It is not proof of application correctness, data quality or an automatically reviewed migration file. The complete fixture exposes candidate operation names so you can connect the proposed schema difference to the specific operation that was actually executed.