Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLA not following metadata naming_convention when using Flask-AppBuilder with Flask-Migrate #2300

Open
mikepalod opened this issue Jan 12, 2025 · 0 comments

Comments

@mikepalod
Copy link

Environment

Flask-Appbuilder version: 4.1.4

pip freeze output:
alembic==1.13.3
Flask-AppBuilder==4.1.4
Flask-Migrate==4.0.7
Flask-SQLAlchemy==2.5.1
SQLAlchemy==1.4.51

Describe the expected results

In migrations versions .py file, foreign key should follow naming convention specified

# Start with https://github.com/dpgaspar/Flask-AppBuilder/tree/master/examples/quickmigrate

# Modify 'models.py'

from flask_appbuilder.security.sqla.models import User

class Company(Model):
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True, nullable=False)

class MyUser(User):
    __tablename__ = "ab_user"
    company_id = Column(Integer, ForeignKey("company.id"), nullable=True)
    company = relationship("Company", foreign_keys=[company_id])

# Modify '__init__.py'

from sqlalchemy import MetaData
naming_convention = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(column_0_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}
db = SQLA(app, metadata=MetaData(naming_convention=naming_convention))

Describe the actual results

In migrations versions .py file, foreign key is being set as None instead of 'fk_ab_user_company_id_company'

    with op.batch_alter_table('ab_user', schema=None) as batch_op:
        batch_op.add_column(sa.Column('company_id', sa.Integer(), nullable=True))
        batch_op.create_foreign_key(None, 'company', ['company_id'], ['id'])

should be

    with op.batch_alter_table('ab_user', schema=None) as batch_op:
        batch_op.add_column(sa.Column('company_id', sa.Integer(), nullable=True))
        batch_op.create_foreign_key(batch_op.f('fk_ab_user_company_id_company'), 'company', ['company_id'], ['id'])

Because the naming convention is not used, this error results when trying to run flask db upgrade

  File "../python3.9/site-packages/alembic/operations/batch.py", line 669, in add_constraint
    raise ValueError("Constraint must have a name")
ValueError: Constraint must have a name

Steps to reproduce

  1. implement changes to models.py and init.py
  2. run the following
    flask db init
    flask db migrate
    flask db upgrade
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant