自动生成迁移时如何让alembic或flask迁移名称外键?

问题描述 投票:0回答:1

我断断续续地解决这个问题已经有一段时间了,奇怪的是找不到一个简单的问题/答案组合。相关问题这里这里。我终于找到了解决方案,所以我会问并回答我自己的问题。

在 Flask SQLAlchemy(和常规 SQLAlchemy)中,您可以有一个像这样的列:

class Character(db.model):
  background_id = db.Column(db.Integer, db.ForeignKey('backgrounds.id'))

当您运行

flask db migrate
alembic revision --autogenerate
时,这将导致如下所示的操作:

def upgrade():
  op.create_foreign_key(None, 'characters', 'backgrounds', ['background_id'], ['id'])

def downgrade():
  op.drop_constraint(None, 'characters', type_='foreignkey')

这里的

None
很糟糕。事实上,如果您稍后尝试降级,这总是会失败,因为
drop_constraint
需要约束的名称。

您可以在每次生成迁移时更改此设置,如下所示:

def upgrade():
  op.create_foreign_key('fk_characters_backgrounds', 'characters', 'backgrounds', ['background_id'], ['id'])

def downgrade():
  op.drop_constraint('fk_characters_backgrounds', 'characters', type_='foreignkey')

这有效!

但是,如果您像我一样,您不想每次使用外键自动生成修订版时都必须记住执行此操作。

所以问题是,我们怎样才能让它自动化?

python sqlalchemy flask-sqlalchemy alembic flask-migrate
1个回答
0
投票

在“命名约定的重要性”部分末尾的此处建议的最佳实践中可以找到此问题的答案。解决方案是将

naming_convention
添加到您的
sqlalchemy
元数据,如下所示:

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"
}

metadata = MetaData(naming_convention=convention)

更具体地说,使用

Flask-SQLAlchemy
,在初始化数据库时执行此操作:

from sqlalchemy import MetaData

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"
}

db = SQLAlchemy(metadata=MetaData(naming_convention=convention))

瞧!如果你运行

autogenerate
,你会得到这个:

def upgrade():
  op.create_foreign_key(op.f('fk_characters_background_id_backgrounds'), 'characters', 'backgrounds', ['background_id'], ['id'])

def downgrade():
  op.drop_constraint(op.f('fk_characters_background_id_backgrounds'), 'characters', type_='foreignkey')

(毫不奇怪)感谢 Flask Migrate 的创建者 Miguel Grinberg 链接到 Alembic 文档中的正确页面,最终让我解决了这个问题! 有人在 Flask Migrate GitHub 上的一个问题中询问过这个问题,Miguel 正确地指出这是一个 Alembic 问题,而不是 Flask Migrate 问题。

© www.soinside.com 2019 - 2024. All rights reserved.