My question: Since Tag is connected to multiple tables via association tables, what would I put for back_populates on Tag. Is back_populates also necessary on the association tables? I'm not sure how to model back_populates in this scenario. See below for further details.
I have the following table structure:

Essentially, I can apply a tag to a source, or to a source key. Here are my models:
class Tag(Base):
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
source_tag_assoc = Table('source_tag_assoc', Base.metadata,
Column('source_id', Integer, ForeignKey('source.id')),
Column('tag_id', Integer, ForeignKey('tag.id'))
)
class Source(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_tag_assoc, back_populates="source")
source_key_tag_assoc = Table('source_tag_assoc', Base.metadata,
Column('source_id', Integer, ForeignKey('source_key.id')),
Column('tag_id', Integer, ForeignKey('tag.id'))
)
class SourceKey(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_key_tag_assoc, back_populates="source_key")
back_populates must point to an actual relationship. If you don't want to define the relationship on both models, then backref should be used instead.
Here's how you'd adapt the models to work with back_populates:
class Tag(Base):
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
source = relationship('Source', secondary=source_tag_assoc, back_populates='tags')
class Source(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_tag_assoc, back_populates="source")
source_key = relationship("SourceKey", secondary=source_key_tag_assoc, back_populates="tags")
class SourceKey(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_key_tag_assoc, back_populates="source_key")
And here's switching to backref, which should result in the exact same as above:
class Tag(Base):
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
class Source(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_tag_assoc, backref="source")
class SourceKey(Base):
id = Column(Integer, primary_key=True, index=True)
tags = relationship("Tag", secondary=source_key_tag_assoc, backref="source_key")
Personally I prefer back_populates, because when you have over a dozen models, it's a lot easier to see all the available relationships when they are explicitly defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With