在SQLAlchemy中继承类之间的正确引用

时间:2018-06-15 19:28:24

标签: python python-3.x sqlalchemy flask-sqlalchemy

假设我们有一些模板,我们后来希望创建多个对象,基于这个模板,保留与该对象的链接,并且还具有向后链接来调用基于该模板创建的对象,所以我们会实现这样的类:

class BasicSentence(db.Model):
    __tablename__ = 'basic_sentences'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(25))
    type = db.Column(db.String(50))         
    __mapper_args__ = {
        'polymorphic_identity': 'basic_sentence',
        'polymorphic_on': type
    }

sentence_layout.py:

class SentenceLayout(BasicSentence, db.Model):
    __tablename__ = 'sentences_layouts'

    id = db.Column(db.Integer, db.ForeignKey('basic_sentences.id'), primary_key=True)

    # RELATIONSHIP
    sentenences = relationship("Sentence",
                                  back_populates="sentence_layout")

    __mapper_args__ = {
        'polymorphic_identity': 'sentence_layout',
        'inherit_condition': id == BasicSentence.id
    }

sentence.py:

class Sentence(BasicSentence, db.Model):
    __tablename__ = 'advertisements'

    id = db.Column(db.Integer, db.ForeignKey('basic_sentences.id'), primary_key=True)

    # Relationships
    sentence_layout_id = db.Column(db.Integer, db.ForeignKey('sentences_layouts.id'))
    sentence_layout = relationship(SentenceLayout, foreign_keys=[sentence_layout_id],
                                        back_populates="advertisements")

    __mapper_args__ = {
        'polymorphic_identity': 'sentence',
        'inherit_condition': id == BasicSentence.id,
    }

问题是这导致:

sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'Join object on basic_sentences(4379708104) and sentences_layouts(4379795752)' and 'Join object on basic_sentences(4379708104) and sentences(4379797488)'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly.

During handling of the above exception, another exception occurred:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship SentenceLayout.sentences - 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.

Python 3.6,SQLAlchemy 1.2.2

那么SQLAlchemy中继承类之间的正确引用是什么?

1 个答案:

答案 0 :(得分:1)

您还需要在foreign_keys上指定SentenceLayout.sentenences参数,而不仅仅是Sentence.sentence_layout关系:

sentenences = relationship("Sentence", foreign_keys=Sentence.sentence_layout_id,
                           back_populates="sentence_layout")

由于圆度,您可能需要使用lambda或字符串:

sentenences = relationship("Sentence", foreign_keys=lambda: full.reference.to.sentence.Sentence.sentence_layout_id,
                           back_populates="sentence_layout")

sentenences = relationship("Sentence", foreign_keys="Sentence.sentence_layout_id",
                           back_populates="sentence_layout")