2017-04-26 35 views
0

我有兩個外鍵的SQLAlchemy的實體,因爲它可以有兩種完全不同的父母中的一方。讓我們用地址客戶供應商用於說明目的。一個地址可以屬於客戶供應商(並可以在我的情況下有孩子)。級聯刪除孤兒與通用協會(多父母)在SQLAlchemy的

我想要一個地址及其子女自動刪除,只要它具有零周的父母,也就是既不是客戶也不是供應商是指它。

我初步實現了這個爲

class Address(Base): 
    __tablename__ = 'addresses' 
    id = Column(Integer, primary_key=True) 
    customer_id = Column(Integer, ForeignKey('customers.id') 
    supplier_id = Column(Integer, ForeignKey('suppliers.id') 
    # etc ... 

據SQLAlchemy的文檔,實現Generic Associations的正規途徑是通過使用表每相關的table-per-協會。這兩個似乎沒有解決,雖然級聯刪除的問題:

  • 表每相關:由於地址有自己的孩子,我會複製下面按有關地址的整個層次。否則,問題只是移動到地址孩子
  • 的table-per-關聯關係:與地址安裝反向引用這似乎是同我的初步實施,除了現在眼前的父母都在該協會的行表。我看不出delete-orphan會在這裏工作。

在sqlalchemy中處理具有通用關聯的delete-orphan級聯的正確方法是什麼?

回答

0

找到了答案。有上那麼,人有這個問題,很多一對多關係(主要是表每關聯是什麼)一對夫婦的relatedquestions。還有,描述瞭如何解決該問題的SQLAlchemy的Wiki條目。

的解決方案是手動基本上做delete-orphan通過實現事件監聽器每次沖水後清理:

@event.listens_for(Session, 'after_flush') 
def delete_address_orphans(session, ctx): 
    if any(isinstance(i, Address) for i in session.dirty): 
     query = session.query(Address).\ 
       filter_by(customer=None, supplier=None) 
     orphans = query.all() 
     for orphan in orphans: 
      session.delete(orphan) 

注意,在我的情況下,我加載孤兒第一而不是簡單地增加.delete()到查詢聲明。這是因爲後者會繞過Address實體上的級聯,因此不會刪除Address的子級。