SQLAlchemy中具有多对多关系的被动删除不会阻止为相关对象发出DELETE

 手机用户2602882697 发布于 2023-01-15 09:26

我试图让SQLAlchemy让我的数据库的外键"删除级联"在两个对象之间的关联表上进行清理.我已经根据文档设置了关系cascadepassive_delete选项.但是,当相关对象加载到主对象的集合中并且主对象从会话中删除时,SQLAlchemy会在辅助表上发出与主对象和辅助对象相关的记录的删除语句.

例如:

import logging

import sqlalchemy as sa
import sqlalchemy.ext.declarative as sadec
import sqlalchemy.orm as saorm

engine = sa.create_engine('sqlite:///')
engine.execute('PRAGMA foreign_keys=ON')

logging.basicConfig()
_logger = logging.getLogger('sqlalchemy.engine')

meta = sa.MetaData(bind=engine)
Base = sadec.declarative_base(metadata=meta)

sess = saorm.sessionmaker(bind=engine)

session = sess()

blog_tags_table = sa.Table(
    'blog_tag_map',
    meta,
    sa.Column('blog_id', sa.Integer, sa.ForeignKey('blogs.id', ondelete='cascade')),
    sa.Column('tag_id', sa.Integer, sa.ForeignKey('tags.id', ondelete='cascade')),
    sa.UniqueConstraint('blog_id', 'tag_id', name='uc_blog_tag_map')
)


class Blog(Base):
    __tablename__ = 'blogs'

    id = sa.Column(sa.Integer, primary_key=True)
    title = sa.Column(sa.String, nullable=False)

    tags = saorm.relationship('Tag', secondary=blog_tags_table, passive_deletes=True,
                              cascade='save-update, merge, refresh-expire, expunge')


class Tag(Base):
    __tablename__ = 'tags'

    id = sa.Column(sa.Integer, primary_key=True)
    label = sa.Column(sa.String, nullable=False)

meta.create_all(bind=engine)

blog = Blog(title='foo')
blog.tags.append(Tag(label='bar'))
session.add(blog)
session.commit()

# sanity check
assert session.query(Blog.id).count() == 1
assert session.query(Tag.id).count() == 1
assert session.query(blog_tags_table).count() == 1


_logger.setLevel(logging.INFO)
session.commit()

# make sure the tag is loaded into the collection
assert blog.tags[0]

session.delete(blog)
session.commit()


_logger.setLevel(logging.WARNING)

# confirm check
assert session.query(Blog.id).count() == 0
assert session.query(Tag.id).count() == 1
assert session.query(blog_tags_table).count() == 0

上面的代码将生成DELETE语句,如下所示:

从blog_tag_map删除WHERE blog_tag_map.blog_id =?AND blog_tag_map.tag_id =?

删除博客WHERE blogs.id =?

有没有办法设置关系,以便没有发布blog_tag_map的DELETE语句?我也试过设置passive_deletes='all'相同的结果.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有