mar*_*and 5 python postgresql sqlalchemy flask 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)
Run Code Online (Sandbox Code Playgroud)
这是我的数据模型的核心。
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')
Run Code Online (Sandbox Code Playgroud)
节点通过Edge定向连接。边缘将src节点连接到dest节点。要注意的一件事是,节点的主键为id,而边缘的主键为type,src且为复合主键dest。由于无法将src或dest设置为NULL的Edge,因此,如果删除了Node,则也必须删除以任何方式引用它的所有Edge。
在该模型中,我relationships在Node和Edge上创建了相互填充的SQLAlchemy 。在节点一侧,我可以访问传入和传出的边缘,并且边缘可以访问其连接的节点。
我想做的是删除图形的子集。为此,我通过从节点开始并遍历节点的out_edges来遍历图。我只是明确删除节点。我依靠在两个节点的关系上配置的级联删除来删除边缘。
如图所示进行配置时,我似乎总是会收到警告,这似乎表明未删除某些内容。但是,如果删除节点的in_edges上的级联删除,则警告消失。
我认为可能发生的事情是,由于边缘必须同时存在两个节点,所以当我删除src节点时,它会删除传出的边缘,然后当我删除这些边缘的目标节点时,它会寻找传入的边缘,但是它已经存在已被删除。
因此,删除级联可解决警告并在某些情况下有效,但是有时我要删除一个节点,该节点的传入Edge的src节点不是我正在行走的节点。因此,确保两个关系都导致删除级联是至关重要的,因此我不认为以这种方式抑制警告是正确的做法。
谁能解释发生了什么事?这是可以忽略的安全吗?我做错了吗?
我认为你的问题是相关的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
}
Run Code Online (Sandbox Code Playgroud)