SQLAlchemy: объединенное наследование с отношениями один-к-одному - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь выполнить следующее объединенное наследование с отношение один к одному структура с SQLAlchemy: Box и Item оба Element s,и Box имеет Item.

UML relationship diagram illustrating inheritance from Box to Element and Item to Element, and aggregation of Item by Box.

Определения классов следующие:

class Element(Base):
    __tablename__ = 'element'

    id = Column(Integer, primary_key=True)
    el_type = Column(String)

    __mapper_args__ = dict(
        polymorphic_identity='element',
        polymorphic_on=el_type,
    )

class Box(Element):
    # Joined table inheritance: Element.
    __tablename__ = 'box'
    id = Column(Integer, ForeignKey('element.id'), primary_key=True)
    __mapper_args__ = dict(polymorphic_identity='box')

    # One-to-one relationship: Item.
    item = relationship('Item',
        back_populates='box', uselist=False)

    def __init__(self, item_name=None):
        self.item = Item(item_name)

class Item(Element):
    # Joined table inheritance: Element.
    __tablename__ = 'item'
    id = Column(Integer, ForeignKey('element.id'), primary_key=True)
    __mapper_args__ = dict(polymorphic_identity='item')

    # One-to-one relationship: Box.
    box_id = Column(Integer, ForeignKey('box.id'))
    box = relationship('Box',
        back_populates='item')

    name = Column(String)

    def __init__(self, name):
        self.name = name

Когда я пытаюсьдля создания экземпляра b = Box('rock') я получаю:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Box.item - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

Теперь я перешел на страницу SQLAlchemy по этому вопросу (отличные документы, я мог бы добавить), ноЯ не уверен, как преодолеть разрыв между их примером и моей ситуацией.Я думал, что это может это исправить:

class Item(Element):
    # ...
    box = relationship('Box',
        back_populates='item', foreign_keys=[id, box_id])
    # ...

... но я получаю ту же ошибку.

Что я делаю не так?


ОБНОВЛЕНИЕ:

Теперь я попытался использовать конструкции ForeignKeyConstraint, чтобы более явно описать желаемое поведение SQLAlchemy;безрезультатно:

class Box(Element):
    # ...
    id = Column(Integer, primary_key=True)
    # ...

    ForeignKeyConstraint([id], ['element.id'])

    # ...

class Item(Element):
    # ...
    id = Column(Integer, primary_key=True)
    # ...

    # One-to-one relationship: Box.
    box_id = Column(Integer)
    box = relationship('Box',
        back_populates='item')

    ForeignKeyConstraint([id, box_id], ['element.id', 'box.id'])

    # ...

Простое AssertionError отброшено на меня (нет описания).Учитывая, что SQLAlchemy имеет хороший опыт создания значимых сообщений об ошибках, можно ли предположить, что это непредвиденная ситуация?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...