[python]通过 alembic 更改外键相关的属性

当我们想修改已有的外键字段属性值时, alembic reversion --autogenerate 无法检查外键属性修改, 需要我们手动写相关的操作语句。

下面以修改外键的 ondeleteonupdate 属性为例,讲解如何修改外键属性。

假设有如下 Model:

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    children = relationship("Child")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))

现在想要修改 Childparent_id 的外键属性:

parent_id = Column(Integer, ForeignKey('parent.id', onupdate='CASCADE', ondelete='CASCADE'))

首先,需要从数据中查看 `` child`` 的建表语句,找到外键名称:

mysql>show create table child;
| child | CREATE TABLE `child` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8 |

child_ibfk_1 即为外键名称

然后通过 alembic reversion 生成一个 version 文件,打开生成的文件编辑内容:

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    # 删除已有外键         外键名称        表名
    op.drop_constraint("child_ibfk_1", "child", type_="foreignkey")
    # 重新添加外键
    op.create_foreign_key(
        "child_ibfk_1",    # 外键名称
        "child",           # 当前表的表名
        "parent",          # 外键指向的目标表的表名
        ["parent_id"],     # 外键列名(字段名)
        ["id"],            # 与目标表的某一列(字段)建立外键关系
        onupdate="CASCADE", ondelete="CASCADE")  # 新增的属性
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    p.drop_constraint("child_ibfk_1", "child", type_="foreignkey")
    op.create_foreign_key(
        "child_ibfk_1",
        "child",
        "parent",
        ["parent_id"],
        ["id"])
    ### end Alembic commands ###

drop_constraintcreate_foreign_key 的基本用法已经在上面的注释中有说明了, 想要更详细的用法,请阅读相应的官方文档。


Comments