2016-03-15 42 views
3

我正在使用SQLAlchemy和PostgreSQL構建一個帶有定向圖數據模型的Python Flask應用程序。我有 設置刪除級聯的麻煩。雖然刪除似乎工作給予基本的檢查,我不確定我是否 可能是我不理解的方式來敗壞的事情,因爲我得到以下警告:如何修復SQLAlchemy:SAWarning:表中的DELETE語句預計刪除1行; 0匹配

SAWarning: DELETE statement on table 'edges' expected to delete 1 row(s); 0 were matched. 
Please set confirm_deleted_rows=False within the mapper configuration to prevent this warning. (table.description, expected,rows_matched) 

這裏是我的數據模型的核心。

class Node(db.Model): 
    __tablename__ = 'nodes' 

    __mapper_args__ = { 
     'polymorphic_on': type, 
     'polymorphic_identity': 'node' 
    } 

    id = Column(BigInteger, primary_key=True) 
    type = Column(String) 

    in_edges = relationship("Edge", cascade="save-update, merge, delete", foreign_keys="Edge.dest", back_populates='dest_node') 
    out_edges = relationship("Edge", cascade="save-update, merge, delete", foreign_keys="Edge.src", back_populates='src_node') 


class Edge(db.Model): 
    __tablename__ = 'edges' 

    __mapper_args__ = { 
     'polymorphic_on': type, 
     'polymorphic_identity': 'edge' 
    } 

    type = Column(String, primary_key="True") 

    src = Column(Integer, ForeignKey('nodes.id'), primary_key=True) 
    dest = Column(Integer, ForeignKey('nodes.id'), primary_key=True) 

    src_node = relationship("Node", foreign_keys=[src], back_populates='out_edges') 
    dest_node = relationship("Node", foreign_keys=[dest], back_populates='in_edges') 

節點通過邊緣以直接方式連接。 Edge's將src節點連接到dest節點。有一件事要注意的是 節點有一個主鍵id,而邊緣有一個複合主鍵type,srcdest。由於 不能有src或dest設置爲NULL的Edge,所以如果一個節點被刪除,那麼所有以任何方式引用它的Edges都必須被刪除。

在該模型中,我在Node和Edge上創建了SQLAlchemy relationships,它們之間互相填充。在節點 一側,我可以訪問傳入和傳出的邊緣,並且邊緣可以訪問它連接的節點。

我想要做的是刪除圖的子集。爲此,我從節點 開始走遍該節點的遍歷圖。我只是明確地刪除節點。我依靠級聯刪除 我已經在兩個節點的關係上配置來照顧刪除邊緣。

當配置如圖所示,我似乎總是得到警告,這似乎表明某些東西沒有被刪除。 但是,如果我刪除節點的in_edges上的級聯刪除,警告消失。

我認爲可能發生的情況是,由於Edge必須同時存在兩個節點,所以當我刪除src節點時,它將刪除傳出的邊,然後當我刪除那些Edge的dest節點時,它會查找傳入邊緣, 但它已被刪除。

因此,刪除級聯修復了警告,並在某些情況下工作,但有時候我刪除節點時, 有一個傳入邊緣,其src節點不是我正在訪問的一個節點。因此,確保兩個關係都會導致刪除級聯是至關重要的,所以我不認爲以這種方式壓制警告是正確的。

任何人都可以解釋發生了什麼?這是安全的忽略?我做錯了嗎?

回答