Applying a Naming Convention to Constraints via SQLAlchemy & Alembic
James
Posted on February 14, 2019
Top Tip!
So we're creating a new database schema, using SQLAlchemy for the ORM and Alembic for the schema management, (if you use Python and need to manage a database sructure I highly recommend these two tools), anyway we just ran into a problem when downgrading a migration that attempted to drop an unnamed Foreign Key.
Wat?!
Why would it allow me to create a constraint that it can't drop, why? Good question, turns out that it's up to you (well me in this case) to name things.
Obviously we don't want to have to remember to do this manually everytime we generate a migration involving a constraint, that would be tedious and prone to error (I will definitely forget to do this), so what do we do?
Well Alembic has you covered, you can set a naming convetion to apply to all migrations, when declaring your Base model class (this should be default behaviour in my opinion, but I'm not hating, nothing but love for you Alembic/SQLAlchemy).
Cut to the chase and tell me how
Well like this;
from sqlalchemy import MetaData
from sqlalchemy.ext.declarative import declarative_base
meta = MetaData(
naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
}
)
Base = declarative_base(metadata=meta)
Source alembic docs for reference are here thank you alembic peeps!
So there you go - simply use the Base in your alembic env.py - and also inherit from Base in all your model classes and you're good to go
You'll see autogenerated migrations like this;
...
sa.PrimaryKeyConstraint('id', name=op.f('pk_thing'))
...
sa.ForeignKeyConstraint(['wotsit_id'], name=op.f('fk_thing_wotsit_id_wotsit')),
...
Enjoy!
Posted on February 14, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.