Python Alembic每次迁移时都会重新创建外键,导致表上出现重复的外键

Python Alembic每次迁移时都会重新创建外键,导致表上出现重复的外键,python,sqlalchemy,flask-sqlalchemy,alembic,flask-migrate,Python,Sqlalchemy,Flask Sqlalchemy,Alembic,Flask Migrate,我有一个flask应用程序,使用sql alchemy和flask迁移来处理数据库更改。每次运行flask migrate为Alembic创建脚本以更新数据库时,该脚本都包含创建数据库中已存在的外键的命令 my models.py中的表定义为 class Airline(db.Model): __tablename__ = 'Airlines' AirlineID = db.Column(db.Integer, primary_key=True)

我有一个flask应用程序,使用sql alchemy和flask迁移来处理数据库更改。每次运行flask migrate为Alembic创建脚本以更新数据库时,该脚本都包含创建数据库中已存在的外键的命令

my models.py中的表定义为

class Airline(db.Model):

    __tablename__ = 'Airlines'
    AirlineID =         db.Column(db.Integer,       primary_key=True)
    AirlineShortCode =  db.Column(db.String(3),     index=True, unique=True, nullable=False)
    FullName =          db.Column(db.String(256),   unique=False, nullable=True)
    ShortName =         db.Column(db.String(64),    unique=False, nullable=True)

class CabinClass(db.Model):

    __tablename__ = 'CabinClasses'
    CabinClassID =         db.Column(db.Integer,     primary_key=True)
    AirlineShortCode =     db.Column(db.ForeignKey("Airlines.AirlineShortCode"), nullable=True)
    CabinClassShortCode =  db.Column(db.String(32),  unique=False, nullable=False)
    CabinClassName =       db.Column(db.String(64),  unique=False, nullable=True)
为创建外键而生成的迁移数据库更新脚本中的行是

    op.create_foreign_key(None, 'CabinClasses', 'Airlines', ['AirlineShortCode'], ['AirlineShortCode'])
每次创建迁移脚本时都会生成这一行,从而在CabinClasses表中生成多个外键条目:

我看到创建的每个外键的名称不同,数据库迁移脚本中的
create\u foreign\u key
命令将名称声明为
None
。如果您使用的是自动命名方案,我相信这是正确的,我相信默认情况下会发生这种情况

对于使用自动命名方案(如所述)的设置 在配置约束命名约定时,此处的名称可以为None, 因为事件侦听器会将名称应用于约束对象 当它与表关联时


有人能确定每次我更新数据库时创建这些外键的原因吗?

您得到的约束名称看起来像来自您的数据库,而不是SQLAlchemy。您需要将所有类型的约束的约束命名模板添加到SQLAlchemy元数据中,然后我认为您将获得一致的名称。看看如何在炼金术中做到这一点。为了方便起见,我从下面的文档中复制了代码示例:

从sqlalchemy导入元数据
从烧瓶进口烧瓶
从flask_sqlalchemy导入sqlalchemy
约定={
“ix”:“ix%(列0标签)s”,
“uq”:“uq%(表名称)s%(列名称)s”,
“ck”:“ck%(表名)s%(约束名)s”,
“fk”:“fk%(表名)s%(列名)s%(引用表名)s”,
“主键”:“主键%(表名)s”
}
元数据=元数据(命名约定=约定)
db=SQLAlchemy(应用程序,元数据=元数据)

谢谢@miguel,我实现了这一点并运行了一个db迁移(我正在使用您的flask迁移(很好))。这创建了一个Alembic迁移文件,其中包含使用新命名约定填充的create_foreign_key语句<代码>op.create_foreign_key(op.f('fk_CabinClasses_AirlineShortCode_Airlines')、'CabinClasses'、'AirlineShortCode']、['AirlineShortCode']、['AirlineShortCode'])我进行了升级并添加了外键,但在运行进一步的db迁移时,它创建了完全相同的create_foreign_key行,使用了新的命名约定,就像上次一样。