删除关系的行为

ton*_*nio 7 python sqlalchemy

这不是一个问题,我只是想了解.考虑以下代码:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()

class AB(Base):
    __tablename__= 'ab'
    id_a = Column(Integer, ForeignKey('a.id', ondelete='CASCADE'), primary_key=True)
    id_b = Column(Integer, ForeignKey('b.id', ondelete='CASCADE'), primary_key=True)
    rel = Column(Unicode)

class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)

class B(Base):
    __tablename__ = 'b'
    id = Column(Integer, primary_key=True)
    #1: doesn’t work try to set id_b to null
    rel_a = relationship('AB')
    # Works, but cascade='all' seems uneeded to me
    rel_a = relationship('AB', cascade='all')
    # Works 
    rel_a = relationship('AB', passive_deletes=True)

engine = create_engine('sqlite://', echo=True)

import logging
logger = logging.getLogger('sqlalchemy.engine.base.Engine')
logger.setLevel(logging.DEBUG)
handler = logger.handlers[0]
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(levelname)s %(message)s', ''))

Base.metadata.create_all(engine)

sess = sessionmaker(engine)()

a1 = A()
b1 = B()
ab = AB()

sess.add_all([a1,b1])
sess.flush()

ab.id_a = a1.id
ab.id_b = b1.id
ab.rel = u'truite'
sess.add(ab)
sess.flush()
sess.delete(b1)
sess.flush()
Run Code Online (Sandbox Code Playgroud)

我希望AB删除相关记录时删除表中的记录B.我尝试了3种关系(检查B表):

  • 1:不起作用(AssertionError:依赖关系规则试图在实例''上删除主键列'ab.id_b'),而如果尝试直接在数据库中删除它,则正确使用约束,并从AB记录被删除.

  • 2:工作,我不明白为什么这是必要的,因为生成的数据库是相同的(你可以检查输出上的差异)

  • 3:工作,DB约束做功.

离开(3),我不明白为什么(2)是必需的,因为ondelete='cascade'已经设置,并且生成的DB是相同的.我的猜测是(1),SQLAlchemy有足够的信息来保持正确的行为.

我错过了什么吗?谢谢.

Xio*_*ion 10

cascadeon relationship配置级联Session操作,例如Session.delete.它独立ON X CASCADE于您对数据库本身的外键约束的任何指令.

在您的情况下,cascade='all'告诉SQLAlchemy将Session.delete(从其他操作中)从父对象(AB)级联到子对象.没有它,默认的操作模式是将NULL放入外键列并让引用的对象成为.

另一方面,passive_deletes=True指示SQLAlchemy依靠数据库通过ON DELETE CASCADE指令清除已删除的对象.这可以防止SQLAlchemy DELETE自行发出查询,就像在relationship(cascade=...)案例中一样.

  • 这是你读过的doc部分吗?http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#cascades多年来我已修改过几十次这个部分,还需要更多吗?减 ?是什么让你失望的? (5认同)