Alembic,如何修改ForeignKey列

13

我正在使用Alembic 0.8.9,SQLAlchemy 1.1.4,并且我的数据库是MySQL数据库。
我正在修改一个表和一个外键列:

在我的数据库中,我将'organs'表重命名为'purposes'。 使用以下命令:

from alembic import op

def upgrade():
    op.rename_table('organs', 'purposes')
在那之后,我想要更新另一个表中的外键:
之前
class Order(DeclarativeBase):
    __tablename__ = 'orders'
    id = Column(Integer, autoincrement=True, primary_key=True)

    organ_id = Column(Integer, ForeignKey('organs.id'))

之后

class Order(DeclarativeBase):
    __tablename__ = 'orders'
    id = Column(Integer, autoincrement=True, primary_key=True)

    purpose_id = Column(Integer, ForeignKey('purposes.id'))

我需要帮助编写一个Alembic迁移脚本,以便在数据库中反映这个更改。如何修改外键列?

感谢您的帮助。


为什么要“修改”?这似乎更像是“删除organ_id,添加purpose_id”。 - sebastian
3
如果我删除并添加,我的数据不会丢失吗?我还将表格的名称从“organs”改为“purposes”。 - A-Palgy
没错 - 我不知道你的真实目标是重命名外部表。在这种情况下,我的删除和创建确实是没有意义的,我想。 - sebastian
谢谢,我已经更新了问题。 - A-Palgy
MySQL的主题文档很令人困惑。另一方面,“指向重命名表的外键不会自动更新。在这种情况下,您必须删除并重新创建外键,以使其正常工作。”,但测试和此错误报告似乎表明相反的情况。如果错误报告被证实是正确的,那么在重命名表之后,您只需执行op.alter_column('orders', 'organ_id', new_column_name='purpose_id')即可。 - Ilja Everilä
1个回答

17

感谢有帮助的评论,这些评论促使我进一步了解了SQL外键。我现在想我已经懂了。
这个回答为我指明了方向:
如何更改Foreign Key引用行为?

基本上,我需要做的是重命名列(保存数据的列),删除旧的外键约束,然后创建一个新的外键约束。

以下是我的迁移脚本:

from alembic import op
import sqlalchemy as sa


def upgrade():
    op.rename_table('organs', 'purposes')
    op.alter_column('orders', 'organ_id', new_column_name='purpose_id', existing_type=sa.Integer)
    op.drop_constraint(constraint_name="orders_ibfk_2", table_name="orders", type_="foreignkey")
    op.create_foreign_key(
        constraint_name="orders_ibfk_2",
        source_table="orders",
        referent_table="purposes",
        local_cols=["purpose_id"],
        remote_cols=["id"])


def downgrade():
    op.rename_table('purposes', 'organs')
    op.alter_column('orders', 'purpose_id', new_column_name='organ_id', existing_type=sa.Integer)
    op.drop_constraint(constraint_name="orders_ibfk_2", table_name="orders", type_="foreignkey")
    op.create_foreign_key(
        constraint_name="orders_ibfk_2",
        source_table="orders",
        referent_table="organs",
        local_cols=["organ_id"],
        remote_cols=["id"])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接