【问题标题】:How to fix SQLAlchemy: SAWarning: DELETE statement on table expected to delete 1 row(s); 0 were matched如何修复 SQLAlchemy:SAWarning:表上的 DELETE 语句预计将删除 1 行; 0 匹配
【发布时间】:2016-06-30 09:11:02
【问题描述】:

我正在使用 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')

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

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

我想要做的是删除图表的一个子集。为此,我从一个节点开始遍历图表 并遍历节点的 out_edges。我只是明确删除节点。我依靠级联删除 我已经对节点的两个关系进行了配置,以负责删除边缘。

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

我认为可能发生的情况是,由于 Edge 必须同时存在两个节点,所以当我删除 src 节点时, 它删除传出的边缘,然后当我删除那些边缘的目标节点时,它会查找传入的边缘, 但它已经被删除了。

因此,删除级联可以修复警告并在某些情况下有效,但有时我删除的节点会 有一个传入的边缘,其 src 节点不是我在步行时访问的节点。因此,确保两者都至关重要 关系会导致删除级联,因此我认为以这种方式抑制警告不是正确的做法。

谁能解释发生了什么?这可以安全忽略吗?我做错了吗?

【问题讨论】:

    标签: python postgresql flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    我认为您的问题与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
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-26
      • 2013-04-02
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 2020-06-02
      • 1970-01-01
      相关资源
      最近更新 更多