Reputation: 1279
Let's say we have some template and we later wish to create multiple objects, based on this template, preserving link to this object and also having backward link to call the objects created based on this template, so we would implement classes like this:
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,
}
Problem is that this results in:
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
So what is proper referencing between inherited classes in SQLAlchemy?
Upvotes: 2
Views: 384
Reputation: 20508
You need to specify the foreign_keys
argument on SentenceLayout.sentenences
as well, not just the Sentence.sentence_layout
relationship:
sentenences = relationship("Sentence", foreign_keys=Sentence.sentence_layout_id,
back_populates="sentence_layout")
Because of circularity, you may need to use a lambda or a string instead:
sentenences = relationship("Sentence", foreign_keys=lambda: full.reference.to.sentence.Sentence.sentence_layout_id,
back_populates="sentence_layout")
or
sentenences = relationship("Sentence", foreign_keys="Sentence.sentence_layout_id",
back_populates="sentence_layout")
Upvotes: 1