我试图实现一个面向用户的文章预览列表,即使删除了Article
,它也会保持其大小。因此,如果列表有四个对象[1, 2, 3, 4]
并且其中一个被删除,我希望它包含[1, 2, None, 4]
。在
我使用的是secondary
表的关系。目前,删除Article
或PreviewList
将删除该表中的行。我尝试过级联选项,但它们似乎直接影响相关项,而不是secondary
表的内容。在
下面的代码片段测试所需的行为:删除Article
应该保留ArticlePreviewListAssociation
中的行,但是删除PreviewList
应该删除它(而不是{
在下面的代码中,删除Article
将保留ArticlePreviewListAssociation
,但是pl.articles
不会将其视为列表项。在
from db import DbSession, Base, init_db
from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy.orm import relationship
session = DbSession()
class Article(Base):
__tablename__ = 'articles'
id = Column(Integer, primary_key=True)
title = Column(String)
class PreviewList(Base):
__tablename__ = 'preview_lists'
id = Column(Integer, primary_key=True)
articles = relationship('Article', secondary='associations')
class ArticlePreviewListAssociation(Base):
__tablename__ = 'associations'
article_id = Column(Integer, ForeignKey('articles.id'), nullable=True)
previewlist_id = Column(Integer, ForeignKey('preview_lists.id'), primary_key=True)
article = relationship('Article')
preview_list = relationship('PreviewList')
init_db()
print(f"Creating test data")
a = Article(title="StackOverflow: 'Foo' not setting 'Bar'?")
pl = PreviewList(articles=[a])
session.add(a)
session.add(pl)
session.commit()
print(f"ArticlePreviewListAssociations: {session.query(ArticlePreviewListAssociation).all()}")
print(f"Deleting PreviewList")
session.delete(pl)
associations = session.query(ArticlePreviewListAssociation).all()
print(f"ArticlePreviewListAssociations: should be empty: {associations}")
if len(associations) > 0:
print("FAIL")
print("Reverting transaction")
session.rollback()
print("Deleting article")
session.delete(a)
articles_in_list = pl.articles
associations = session.query(ArticlePreviewListAssociation).all()
print(f"ArticlePreviewListAssociations: should not be empty: {associations}")
if len(associations) == 0:
print("FAIL")
print(f"Articles in PreviewList: should not be empty: {articles_in_list}")
if len(articles_in_list) == 0:
print("FAIL")
# desired outcome: pl.articles should be [None], not []
print("Reverting transaction")
session.rollback()
这可以归结为“你如何建立一个多对多的关系,其中pk_A == 1 and pk_B == NULL
包含在a的列表中在
所举的例子似乎假定相关条款的顺序是保持不变的,即使在删除时也是如此。有多种方法可以实现这一点,例如Ordering List扩展,但是首先解决与已删除文章的关联的问题更容易。这看起来像是association object和{a3}的用例。在
Article
类获得一个新的关系,以便在会话中级联删除。默认的ORM-level cascading行为是将外键设置为NULL,但是如果没有加载相关的关联对象,我们希望让数据库执行此操作,因此使用passive_deletes=True
:{many-association.{many-association-to-many-association-of-many-object-to-many-association-of-many-object-to-association-of-many-object-to-association-of-many-object-to-association,而不是。这一次级联有点不同,因为如果父对象
^{pr2}$PreviewList
被删除,则应该删除关联对象:最初,association对象使用
previewlist_id
作为主键,但是PreviewList
只能包含一个Article
。代理键解决了这个问题。外键配置包括DB级级联。以下是使用被动删除的原因:有了这些更改,就不会打印“失败”。在
相关问题 更多 >
编程相关推荐