SQLAlchemy Несколько связей между таблицами - PullRequest
0 голосов
/ 15 февраля 2019

Два декларативных класса, у которых есть родительские дочерние отношения, самый младший дочерний элемент - самый важный дочерний, поэтому столбец 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 голосов
/ 15 февраля 2019

Вы определили foreign_keys для отношения youngest_child, но вы также должны определить его для отношений children и parent:

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])

Кроме того, вы должны определить post_update=True, например, youngest_child, чтобы разорвать круговую зависимость между моделями.Без этого SQLAlchemy пришлось бы вставлять одновременно и родителя, и потомка, если вы сделаете что-то вроде этого:

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

После установки обновления SQLAlchemy сначала вставляется в родителей, затем в детей,а затем обновляет родителя младшим ребенком.

...