【问题标题】:SQLAlchemy update objects treeSQLAlchemy 更新对象树
【发布时间】:2021-05-22 06:21:25
【问题描述】:

我正在尝试构建对象树。该类如下所示:

class Node(BaseModel, db.Model):
    '''Node model'''
    __tablename__ = 'network_nodes'
    id = Column(String(10), primary_key=True)
    parent_id = Column(String(10), ForeignKey('network_nodes.id'))
    parent = relationship("Node", foreign_keys=[parent_id], lazy='dynamic')
    left_id = Column(String(10), ForeignKey('network_nodes.id'))
    left = relationship("Node", foreign_keys=[parent_id], lazy='dynamic')
    right_id = Column(String(10), ForeignKey('network_nodes.id'))
    right = relationship("Node", foreign_keys=[parent_id], lazy='dynamic')

每当添加新叶子时,都会执行此代码:

node.left_id = element_id
left = Node(id=element_id, parent_id=node.id)
db.session.add(left)

有时我会使用db.session.commit() 提交所有更改。在commit() 点,我看到会话中的脏对象和新对象。但是提交失败并出现错误:

(MySQLdb._exceptions.IntegrityError) (1452, '无法添加或更新子行:外键约束失败 (db.network_nodes, CONSTRAINT network_nodes_ibfk_2 FOREIGN KEY (left_id) 参考@987654329 @ (id))') [SQL: UPDATE network_nodes SET left_id=%s, right_id=%s WHERE network_nodes.id = %s] [参数:('S5837124','S5839010','S5832131')]

我假设脏对象在新对象之前提交。因此left_id 指的是尚未存在的记录。

如何在脏对象之前提交新对象?

【问题讨论】:

    标签: python sqlalchemy mysql-python


    【解决方案1】:

    如何在脏对象之前提交新对象?

    您可以添加所有对象,刷新新对象,然后提交整个批次:

        left = Node(id=element_id, parent_id=node.id)
        session.add(left)
        node.left_id = element_id
        
        session.flush(session.new)
        session.commit()
    

    【讨论】:

    • 这是否意味着每次添加对象时都必须刷​​新会话?我每笔交易最多添加 2000 个对象。这样的冲洗不会影响性能吗?
    • 我已经用替代解决方案更新了我的答案。
    • 谢谢。第二个选项我更喜欢,但不幸的是,后来创建的对象依赖于之前创建的对象,我最终遇到了同样的问题。所以我必须在每个对象创建后使用第一个选项并刷新会话。
    猜你喜欢
    • 2019-06-28
    • 2014-04-16
    • 2014-11-05
    • 2014-06-02
    • 2013-09-20
    • 2011-12-04
    • 2013-10-28
    • 2019-08-21
    相关资源
    最近更新 更多