如何在Sqlalchemy Oracle中实现级联删除?

发布于 2025-02-12 18:07:29 字数 1317 浏览 0 评论 0原文

我正在做API服务,并尝试为附件类删除级联。一直以来,我都会收到integiry错误((cx_oracle.integrityerror)ORA-02292 :)试图删除帖子时。我已经尝试了BackRef/back_populate,使用cascade ='all,delete -orphan'等播放 - 同样的错误。 DB是Oracle。输出来自Insp.get_foreign_keys(“ CRM_POST_ATTACHMATGENTS”) is:

[{'name': 'sys_c00310238', 'constrained_columns': ['post_id'], 'referred_schema': None, 'referred_table': 'crm_post', 'referred_columns': ['id'], 'options': {}}]

以下是当前模型:

class Post(Base):
__tablename__ = "crm_post"

id = Column(Integer, primary_key=True, index=True)
title = Column(String(255), nullable=False)
text = Column(String)
img = Column(LargeBinary)
author_id = Column(Integer, ForeignKey("crm_user.id"), nullable=False)
sdate = Column(DateTime)
edate = Column(DateTime)
post_type = Column(Integer, ForeignKey("crm_dir_post_types.id"), nullable=False)
attachments = relationship("PostAttachments", back_populates="post", passive_deletes=True, cascade='all, delete-orphan')


class PostAttachments(Base):
    __tablename__ = "crm_post_attachments"

id = Column(Integer, primary_key=True, index=True)
attachment = Column(LargeBinary)
post_id = Column(Integer, ForeignKey("crm_post.id", ondelete='CASCADE'), nullable=False)
post = relationship("Post", back_populates="attachments", passive_deletes=True)

I'm doing an API service and trying to do cascade deleting for Attachments class. All the time I get integiry error ((cx_Oracle.IntegrityError) ORA-02292:)when trying to delete a post. I've tried backref/back_populates, played with cascade='all, delete-orphan' etc - the same error. DB is Oracle. Output from insp.get_foreign_keys("crm_post_attachments") is:

[{'name': 'sys_c00310238', 'constrained_columns': ['post_id'], 'referred_schema': None, 'referred_table': 'crm_post', 'referred_columns': ['id'], 'options': {}}]

Here are the current models:

class Post(Base):
__tablename__ = "crm_post"

id = Column(Integer, primary_key=True, index=True)
title = Column(String(255), nullable=False)
text = Column(String)
img = Column(LargeBinary)
author_id = Column(Integer, ForeignKey("crm_user.id"), nullable=False)
sdate = Column(DateTime)
edate = Column(DateTime)
post_type = Column(Integer, ForeignKey("crm_dir_post_types.id"), nullable=False)
attachments = relationship("PostAttachments", back_populates="post", passive_deletes=True, cascade='all, delete-orphan')


class PostAttachments(Base):
    __tablename__ = "crm_post_attachments"

id = Column(Integer, primary_key=True, index=True)
attachment = Column(LargeBinary)
post_id = Column(Integer, ForeignKey("crm_post.id", ondelete='CASCADE'), nullable=False)
post = relationship("Post", back_populates="attachments", passive_deletes=True)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凡尘雨 2025-02-19 18:07:29

来自Insp.get_foreign_keys的输出(“ CRM_POST_ATTACHMENTS”)显示数据库中的实际表不匹配您的ORM模型。该模型指定

    post_id = Column(
        Integer, ForeignKey("crm_post.id", ondelete="CASCADE"), nullable=False
    )

但表从表中反映的外键显示了

[
    {
        'name': 'sys_c00310238', 
        'constrained_columns': ['post_id'], 
        'referred_schema': None, 
        'referred_table': 'crm_post', 
        'referred_columns': ['id'], 
        'options': {}
    }
]

选项 dict表示没有级联规则有效。 vassive_deletes = true告诉sqlalchemy不要打扰级联删除,因为后端会处理它。

为了匹配您的模型,表中的FK应该具有'选项':{'onDelete':'Cascade'}。如果您丢弃FK并使用该选项重新创建它,即,

ALTER TABLE crm_post_attachments 
  ADD FOREIGN KEY(post_id) REFERENCES crm_post (id) ON DELETE CASCADE

您的代码(使用passive_deletes = true)应该有效。

The output from insp.get_foreign_keys("crm_post_attachments") shows that the actual table in the database does not match your ORM model. The model specifies

    post_id = Column(
        Integer, ForeignKey("crm_post.id", ondelete="CASCADE"), nullable=False
    )

but the reflected Foreign Key from the table shows

[
    {
        'name': 'sys_c00310238', 
        'constrained_columns': ['post_id'], 
        'referred_schema': None, 
        'referred_table': 'crm_post', 
        'referred_columns': ['id'], 
        'options': {}
    }
]

The empty options dict indicates that no cascade rule is in effect. passive_deletes=True is telling SQLAlchemy not to bother taking care of cascading the deletes because the backend will handle it.

In order to match your model the FK in the table should have 'options': {'ondelete': 'CASCADE'}. If you drop the FK and re-create it with that option, i.e.,

ALTER TABLE crm_post_attachments 
  ADD FOREIGN KEY(post_id) REFERENCES crm_post (id) ON DELETE CASCADE

then your code (with passive_deletes=True) should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文