SQLAlchemy表之间的多重关系

时间:2019-02-15 06:20:40

标签: python orm sqlalchemy foreign-keys

两个具有父子关系的声明性类,最小的孩子是最重要的孩子,因此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来实现吗?

1 个答案:

答案 0 :(得分:0)

您已经为foreign_keys关系定义了youngest_child,但是还必须为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首先插入父母,然后插入孩子,然后用最小的孩子更新父母。