I would like to change the standard naming conventions of constraints that are set in Flask-SQLAlchemy, to ease migrations with Alembic.
As Flask-SQLAlchemy creates the declarative base (where you can supply naming conventions) by itself I'm not sure what the best way is going about doing this. Can I change naming conventions after the declarative base is created (i.e. when I've created the Flask-SQLAlchemy object) or do I have to subclass the SQLAlchemy class? Is there a completely different way?
One of which is that Flask-SQLAlchemy has its own API. This adds complexity by having its different methods for ORM queries and models separate from the SQLAlchemy API. Another disadvantage is that Flask-SQLAlchemy makes using the database outside of a Flask context difficult.
If set to True , Flask-SQLAlchemy will track modifications of objects and emit signals. The default is None , which enables tracking but issues a warning that it will be disabled by default in the future. This requires extra memory and should be disabled if not needed.
Unique constraints can be created anonymously on a single column using the unique keyword on Column . Explicitly named unique constraints and/or those with multiple columns are created via the UniqueConstraint table-level construct.
create_all() function to create the tables that are associated with your models. In this case you only have one model, which means that the function call will only create one table in your database: from app import db, Student.
As of Flask-SQLAlchemy 2.1 you can do the following:
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
metadata = MetaData(
naming_convention={
'pk': 'pk_%(table_name)s',
'fk': 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s',
'ix': 'ix_%(table_name)s_%(column_0_name)s',
'uq': 'uq_%(table_name)s_%(column_0_name)s',
'ck': 'ck_%(table_name)s_%(constraint_name)s',
}
)
db = SQLAlchemy(metadata=metadata)
Version 2.1 introduced the metadata
argument to the extension. If all you want to customize about the base model is the metadata, you can pass a custom MetaData
instance to it.
db = SQLAlchemy(metadata=MetaData(naming_convention={
'pk': 'pk_%(table_name)s',
'fk': 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s',
'ix': 'ix_%(table_name)s_%(column_0_name)s',
'uq': 'uq_%(table_name)s_%(column_0_name)s',
'ck': 'ck_%(table_name)s_%(constraint_name)s',
}))
Previously, you would subclass the SQLAlchemy
class and override make_declarative_base
. This still works, and is useful if you need to further customize the base model.
from flask_sqlalchemy import SQLAlchemy as BaseSQLAlchemy, Model, _BoundDeclarativeMeta, _QueryProperty
from sqlalchemy import MetaData
class SQLAlchemy(BaseSQLAlchemy):
def make_declarative_base(self):
metadata = MetaData(naming_convention={
'pk': 'pk_%(table_name)s',
'fk': 'fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s',
'ix': 'ix_%(table_name)s_%(column_0_name)s',
'uq': 'uq_%(table_name)s_%(column_0_name)s',
'ck': 'ck_%(table_name)s_%(constraint_name)s',
})
base = declarative_base(metadata=metadata, cls=Model, name='Model', metaclass=_BoundDeclarativeMeta)
base.query = _QueryProperty(self)
return base
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With