使用 sqlalchemy 将 onupdate="cascade" 添加到 postgres 中的现有列

Posted

技术标签:

【中文标题】使用 sqlalchemy 将 onupdate="cascade" 添加到 postgres 中的现有列【英文标题】:Add onupdate="cascade" to existing column in postgres with sqlalchemy 【发布时间】:2021-02-05 05:54:29 【问题描述】:

我想在现有表中的ForeignKey 对象上添加onupdate="cascade"

我有一个使用关联对象的多对多关系:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, create_engine
from sqlalchemy.orm import relationship

postgres_url = "postgresql:/username:pwd@localhost/myDB"
engine = create_engine(postgres_url)
Base = declarative_base()
Base.metadata.create_all(engine)

class VehicleType(Base):
    __tablename__ = 'vehicleTypes'

    name = Column(String, primary_key=True)

class SearchTermToVehicleType(Base):
    __tablename__ = "searchTermToVehicleType"

    searchTermName = Column(String, ForeignKey('searchTerms.name'), primary_key=True)
    vehicleTypeName = Column(String, ForeignKey('vehicleTypes.name'), primary_key=True)

class SearchTerm(Base):
    __tablename__ = 'searchTerms'

    name = Column(String, primary_key=True)
    vehicleTypes = relationship("VehicleType", secondary="searchTermToVehicleType")

这已经在生产中,但现在我需要允许用户更改搜索词名称。似乎使用关联表 sqlalchemy 会自动执行 ondelete="cascade" 但不是 onupdate="cascade" 所以现在我想更改我的模型以将其包含在关联表上的 ForeignKey 对象中,以便我可以简单地更改 name 的任何searchTerm

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, create_engine
from sqlalchemy.orm import relationship

postgres_url = "postgresql:/username:pwd@localhost/myDB"
engine = create_engine(postgres_url)
Base = declarative_base()
Base.metadata.create_all(engine)

class VehicleType(Base):
    __tablename__ = 'vehicleTypes'

    name = Column(String, primary_key=True)

class SearchTermToVehicleType(Base):
    __tablename__ = "searchTermToVehicleType"

    searchTermName = Column(
        String, 
        ForeignKey('searchTerms.name', onupdate="cascade"), 
        primary_key=True
    )
    vehicleTypeName = Column(String, ForeignKey('vehicleTypes.name'), primary_key=True)

class SearchTerm(Base):
    __tablename__ = 'searchTerms'

    name = Column(String, primary_key=True)
    vehicleTypes = relationship("VehicleType", secondary="searchTermToVehicleType")

但这不会改变现有的底层 postgres 表。我可以删除 SearchTermSearchTermToVehicleType 表并让 sqlalchemy 再次构建它们,但我不想重新填充它们。

文档提到这使用了数据库的 ON UPDATE CASCADE 功能。如何更改现有表或列以实现上述结果?还是我必须删除并重建表?

【问题讨论】:

【参考方案1】:

您需要在您的 postgresql 数据库上运行 DROP CONSTRAINTADD CONSTRAINT sql 命令来更改现有约束以添加 on update cascade

ALTER TABLE ...
DROP CONSTRAINT ...,
ADD CONSTRAINT ... FOREIGN KEY ... ON UPDATE CASCADE;

要自动化架构管理 - 请查看 Alembic 项目。

【讨论】:

以上是关于使用 sqlalchemy 将 onupdate="cascade" 添加到 postgres 中的现有列的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy - Column详解

SQLAlchemy学习-7.Column 设置日期时间类型

为啥不为不可见组件触发 OnUpdate [重复]

如何在 onUpdate 函数中通过从同一集合中读取来更新同一文档

OnUpdate() 未调用小部件服务

OnUpdate 在 Android Widget 中的 onReceive 之前调用