查询删除不会从关联中删除条目 table

Query deletion does not remove entries from association table

我为自引用多对多关系实现了关联 table。与 SQLAlchemy documentation 中描述的类似。但是,当我使用 session.query(Node).delete() 删除所有节点对象时,关联 table 保留其条目。

可重现的例子:

a, b = Node(), Node()
a.children = [b]
session.add_all([a, b])
session.commit()
session.query(Node).delete()
session.commit()
assert(session.query(Node).count() == 0)
assert(session.query(link).count() == 0)

型号:

Base = declarative_base()    
link = Table('link', Base.metadata,
             Column('parent', Integer, ForeignKey('node.id')),
             Column('child', Integer, ForeignKey('node.id')))

class Node(Base):
    __tablename__ = 'node'
    id = Column(Integer, primary_key=True)
    children = relationship('Node',
                            secondary=link,
                            primaryjoin=id == link.c.parent,
                            secondaryjoin=id == link.c.child,
                            backref='parents')

第一个断言按预期通过。第二个断言失败。 (1 != 0)

如果我将 session.query(Node).delete() 替换为:

session.delete(a)

session.delete(b)

...然后断言按预期通过。

Node table 中删除所有对象以确保 link table 中的相应条目被删除的正确方法是什么?

SQLAlchemy documentation中所述,关于Query.delete()

The method does not offer in-Python cascading of relationships - it is assumed that ON DELETE CASCADE/SET NULL/etc. is configured for any foreign key references which require it, otherwise the database may emit an integrity violation if foreign key references are being enforced.

我最后只写了删除如下:

for node in session.query(Node).all():
    session.delete(node)

这比批量删除效率低得多。为了提高运行速度,需要在DBMS层面正确配置外键。