How to write alter column name migrations with sqlalchemy-migrate? How to write alter column name migrations with sqlalchemy-migrate? sqlite sqlite

How to write alter column name migrations with sqlalchemy-migrate?


This one also works:

from alembic import op....def upgrade(migrate_engine):    op.alter_column('users', 'user_id', new_column_name='id')def downgrade(migrate_engine):    op.alter_column('users', 'id', new_column_name='user_id')


Turns out there's an even DRY:er solution to this than I had hoped for. Introspection! Like so:

def upgrade(migrate_engine):    meta = MetaData(bind=migrate_engine)    users = Table('users', meta, autoload=True)    users.c.user_id.alter(name='id')def downgrade(migrate_engine):    meta = MetaData(bind=migrate_engine)    users = Table('users', meta, autoload=True)    users.c.id.alter(name='user_id')

Works like a charm!


I bet that it can't generate any SQL because your metadata references are getting mixed up. You seem to be using two different metadata objects in your Table classes, and that's really not good. You only need one. The metadata tracks stale-ness of objects, whether it needs to issue queries for object updates, foreign key constraints, etc. and it needs to know about all your tables and relationships.

Change to use a single MetaData object, and pass echo=True to your sqlalchemy.create_engine call and it will print the SQL query that it's using to standard output. Try executing that query yourself while logged in as the same role (user) to Postgres. You may find that it's a simple permissions issue.

Regarding copy-pasting: I think Django has a good convention of placing Table and declarative classes in their own module and importing them. However, because you have to pass a MetaData object to the Table factory, that complicates matters. You can use a singleton/global metadata object, or just convert to declarative.

For a while I chose to implement one-argument functions that returned Table objects given a metadata and cached the result--in effect implementing a singleton model class. Then I decided that was silly and switched to declarative.