如何修复SQLAlchemy:SAWarning:DELETE语句在表上预计删除1行; 0匹配

时间:2016-03-15 04:21:44

标签: python postgresql flask sqlalchemy flask-sqlalchemy

我正在使用SQLAlchemy和PostgreSQL构建一个带有定向图数据模型的Python Flask应用程序。我有 设置删除级联时遇到问题。虽然删除似乎在初步检查时起作用,但我不确定是否可以 可能会以我不理解的方式破坏事物,因为我收到以下警告:

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')

节点由Edges以定向方式连接。 Edge将src节点连接到dest节点。有一点需要注意的是 Node的主键为id,而Edge的复合主键为typesrcdest。自从你 不能将src或dest设置为NULL的Edge,如果删除了一个Node,那么以任何方式引用它的所有Edges都必须 也被删除。

在模型中,我在Node和Edge上创建了SQLAlchemy relationships,它们相互填充。在节点上 我可以访问传入和传出的边缘,Edge可以访问它连接的节点。

我要做的是删除图表的子集。要做到这一点,我正在从节点开始走图表 并遍历Node的out_edges。我只是明确删除节点。我依靠级联删除 我已经配置了Node的两个关系来处理删除Edges。

如图所示进行配置时,我似乎总是收到警告,这似乎表明某些内容未被删除。 但是,如果我删除Node的in_edges上的级联删除,警告就会消失。

我认为可能会发生的事情是,因为当我删除src节点时,Edge必须同时存在两个节点, 它会删除传出的边缘,然后当我删除这些Edge的dest节点时,它会查找传入的边缘,  但它已被删除。

因此删除级联会修复警告并在某些情况下有效,但有时我会删除一个节点 有一个传入的Edge,它的src节点不是我在漫步时访问的节点。因此,确保两者都是批判性的 关系导致删除级联,所以我不认为以这种方式抑制警告是正确的做法。

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

1 个答案:

答案 0 :(得分:2)

我认为您的问题与https://bitbucket.org/zzzeek/sqlalchemy/issues/2403/work-around-mysql-innodb-bug-need-per

有关

您可以尝试使用此代码。

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

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