2016-03-15 148 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节点不是我正在访问的一个节点。因此,确保两个关系都会导致删除级联是至关重要的,所以我不认为以这种方式压制警告是正确的。

任何人都可以解释发生了什么?这是安全的忽略?我做错了吗?

回答