我正在使用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
,src
和dest
。由於 不能有src或dest設置爲NULL的Edge,所以如果一個節點被刪除,那麼所有以任何方式引用它的Edges都必須被刪除。
在該模型中,我在Node和Edge上創建了SQLAlchemy relationships
,它們之間互相填充。在節點 一側,我可以訪問傳入和傳出的邊緣,並且邊緣可以訪問它連接的節點。
我想要做的是刪除圖的子集。爲此,我從節點 開始走遍該節點的遍歷圖。我只是明確地刪除節點。我依靠級聯刪除 我已經在兩個節點的關係上配置來照顧刪除邊緣。
當配置如圖所示,我似乎總是得到警告,這似乎表明某些東西沒有被刪除。 但是,如果我刪除節點的in_edges上的級聯刪除,警告消失。
我認爲可能發生的情況是,由於Edge必須同時存在兩個節點,所以當我刪除src節點時,它將刪除傳出的邊,然後當我刪除那些Edge的dest節點時,它會查找傳入邊緣, 但它已被刪除。
因此,刪除級聯修復了警告,並在某些情況下工作,但有時候我刪除節點時, 有一個傳入邊緣,其src節點不是我正在訪問的一個節點。因此,確保兩個關係都會導致刪除級聯是至關重要的,所以我不認爲以這種方式壓制警告是正確的。
任何人都可以解釋發生了什麼?這是安全的忽略?我做錯了嗎?