【问题标题】:SQLAlchemy Multiple relationships between tablesSQLAlchemy 表之间的多重关系
【发布时间】:2023-03-17 04:53:01
【问题描述】:

两个具有父子关系的声明性类,最小的孩子是最重要的孩子,因此 youngest_child_id 列会很有用。

这里有两种关系——从父到子的一对一和从父到子的一对多,但这会创建多个连接路径

类似于以下内容:

class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    youngest_child_id = Column(Integer, foreign_key='Child.id')
    youngest_child = relationship("Child", uselist=False, foreign_keys=[youngest_child_id])
    children = relationship("Child", back_populates='parent')

Class Child(Base):
    __tablename__ = 'children'
    id = id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, foreign_key='Parent.id')
    parent = relationship("Parent", back_populates='children')

我创建的这个和其他一些变体引发了 AmbiguousForeignKeysError:

发生异常:sqlalchemy.exc.AmbiguousForeignKeysError
可以 无法确定父/子表之间的连接条件 关系Parent.children

这是哪里出了问题,可以通过 ORM 实现吗?

【问题讨论】:

    标签: python orm sqlalchemy foreign-keys


    【解决方案1】:

    您已经为youngest_child 关系定义了foreign_keys,但您还必须为childrenparent 关系定义它:

    class Parent(Base):
        __tablename__ = 'parents'
        id = Column(Integer, primary_key=True)
        youngest_child_id = Column(Integer, ForeignKey('children.id'))
        youngest_child = relationship("Child", uselist=False, post_update=True,
                                      foreign_keys=[youngest_child_id])
        # Pass foreign_keys= as a Python executable string for lazy evaluation
        children = relationship("Child", back_populates='parent',
                                foreign_keys='[Child.parent_id]')
    
    class Child(Base):
        __tablename__ = 'children'
        id = id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parents.id'))
        parent = relationship("Parent", back_populates='children',
                              foreign_keys=[parent_id])
    

    此外,您必须在例如youngest_child 上定义post_update=True,以打破模型之间的循环依赖关系。如果没有它,SQLAlchemy 将不得不同时插入父项和子项,如果您执行以下操作:

    p = Parent()
    c1, c2 = Child(), Child()
    p.children = [c1, c2]
    p.youngest_child = c1
    session.add(p)
    session.commit()
    

    随着帖子更新到位,SQLAlchemy 首先插入父母,然后插入孩子,然后用最小的孩子更新父母。

    【讨论】:

      猜你喜欢
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2015-08-05
      • 1970-01-01
      相关资源
      最近更新 更多