Reputation: 413
For some reason, after adding a new column to a model, alembic's command alembic revision --autogenerate
detects a new table and, accordingly, generates a new migration for the whole entity, instead of picking up new columns only.
A model's base class is mentioned in env.py configuration file as target_metadata = MyBase.metadata
, so it's picking up new models. However, when you add a new column, instead of generating a revision with a new column added only, it regenerates the entire model.
Before running alembic revision --autogenerate
, new changes are migrated to db with alembic upgrade head
.
I have a standard declarative_base for my base class and my models extend it.
Is there something else that could go wrong? Probably I am missing out on something obvious ;(
Upvotes: 5
Views: 7207
Reputation: 71
I have been struggling with this issue for hours. I already had the solution above applied and it did not help, the new tables were always being detected. I even played with include_object desribed here with no luck.
I figured the fix by accident. When specifying the schema name make sure it is written in lowercase letters.
Upvotes: 0
Reputation: 101
Most likely this is due to the fact that you are not working in default schema.
The default Alembic behaviour is to scan the default schema and look for changes there. In case you migrate the database to a different schema Alembic will always check the difference between the target_metadata and the default schema resulting in generation of the same migration script each time.
To solve this you should modify the env.py
file in line with this chapter of the Alembic documentation:
Omitting Schema Names from the Autogenerate Process
This includes modifying the context.configure()
section to accept two additional arguments:
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
include_schemas=True,
include_name=include_name,
)
include_schemas
is responsible for allowing Alembic to look for changes in all schemas in database you are connected to.
include_name
is a function where you list schemas be scanned for changes. The function looks like this:
def include_name(name, type_, parent_names):
if type_ == "schema":
return name in [list_of_schemas_to_be_scanned]
else:
return True
Upvotes: 10