On 11/18/2015 06:41 PM, Chris Frey wrote:
> In the alembic documentation, there is an entire page devoted to naming
> constraints:
> 
>       http://alembic.readthedocs.org/en/latest/naming.html
> 
> So I assumed that if constraints had a naming scheme defined, then
> those names would be detected if changed.

if you change your naming convention, then that would show up as a bunch
of brand new constraints in the model and a whole bunch of constraints
removed in the model, so in theory would produce a lot of add constraint
/ drop constraint instructions.


> 
> My specific use case is as follows.  My naming scheme for foreign keys is:
> 
>               "fk": "fk_%(table_name)s_%(column_0_name)s",
> 
> 
>       1) I changed the __tablename__'s and class names of some tables
>               to add a prefix to each.

autogenerate does not detect a change in table name as that, it sees
this as a brand new table added and an old table dropped.  There is no
reasonable way to differentiate a drop/add of two tables from a name
change of a single table.  This limitation is documented at
http://alembic.readthedocs.org/en/latest/autogenerate.html#what-does-autogenerate-detect-and-what-does-it-not-detect.

> 
>       2) I updated the ForeignKey()'s to point to the new table names.

these will not generate add/drops as these FKs are local to the tables
that are being added / dropped (in reality just renamed).


> 
>       3) I then ran alembic autogenerate, which produced drop/create
>               commands for my tables, and some drop/creates for
>               constraints in non-renamed, but affected tables.
>               I manually converted these scripts to use op.rename_table()
>               and removed all the rest.

this is expected.

> 
>       4) I ran alembic upgrade head, which renamed the tables, but
>               not the constraints, as expected.

there is no "rename constraint" migration operation.  There is only add
and drop.   A constraint that changed name in place associated to a
table that did not change its name would produce distinct add/drop
instructions for the old and new constraint.

> 
>       5) Here I expected another alembic revision --autogenerate
>               to give me only the constraint changes, but it said
>               that nothing changed.

if you didn't change your model subsequent to the previous autogenerate
run then I don't see why a second run of autogenerate would do anything new.

> 
> During further experiments, if I removed a ForeignKey(), alembic
> produced an autogenerate script that used the old constraint name
> in the drop_constraint() command.

this is correct.  The database has a constraint named "X", your model
doesn't, it's a drop.

> 
> If I then added the foreign key back, it used the *new* constraint
> name based on the new table name.

also seems correct.   Your model has an FK with the name "Y", your
database doesn't, it's an add.

> 
> Obviously I need to be really careful with renames, but this behaviour
> was somewhat unexpected.  

All Alembic can do with constraints is:

1. get the list of names in the model
2. get the list of names in the DB
3. the names that are only in the DB and not the model are DROPs, the
names that are only in the model and not the DB are ADDs, the
intersection of those names are "do nothing". That's it.


It appears that alembic is already kinda smart
> about matching a table's constraint to the model, even if the names
> don't match.  

SQLAlchemy associates constraints with tables as part of the Python
definition of those models.  It has nothing to do with the names.

Could it also be made smart enough to detect when
> a constraint "rename" is needed? 

since a rename of a table can't be detected, you'd need to write these
out yourself as individual add/drops of constraints; there's not a
feature that automates this.  I can see how it might be useful but I'm
not coming up with what that would look like.  There'd have to be a hook
in the autogenerate process that allows the user to tell autogenerate
that a table is only being renamed, not an add/drop, and then to somehow
rebuild all the constraints with those names.  This would be kind of
intricate but it should be doable as a recipe using the autogenerate
extension system described at
http://alembic.readthedocs.org/en/latest/api/autogenerate.html#customizing-revision-generation.


 If I go to all the trouble to make sure
> my constraints are named properly, it would be nice if alembic helped
> me make sure those names were actually up to date. :-)

I can see this, but that's a big deal to implement.    Getting an
autogenerate extension recipe to do it first would be the best way to start.




> 
> Thanks,
> - Chris
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to