Combining relationships
-
05-06-2021 - |
Вопрос
I have a model Zone
, a model Entity
and a model Transit
. Transit
is minimally defined as:
class Entity(db.Model):
__tablename__ = 'entities'
id = db.Column(db.Integer, primary_key=True)
contained_by = db.Column(db.Integer, db.ForeignKey('entities.id'))
contains = db.relationship('Entity', backref='container')
discriminator = db.Column('type', db.String(50))
__mapper_args__ = {'polymorphic_on': discriminator}
class Zone(Entity):
__mapper_args__ = {'polymorphic_identity': 'zones'}
routes = db.relationship('Transit')
(stuff goes here)
class Transit(db.Model):
__tablename__ = "transits"
start = db.Column(db.Integer, db.ForeignKey('zones.id'))
end = db.Column(db.Integer, db.ForeignKey('zones.id'))
Zone
also has a couple of bits about distance and how defensible it is, but that is irrelevant for this.
- First off, due to the fact that
Zone
is subclassed fromEntity
using single-table inheritance can I referencezones.id
? - Secondly, will the
Zone.routes
property mergeTransit.start
andTransit.end
?
Решение
- no, you need to use the table name, which in your case (Single-table inheritance) is
entities
- no, these will not be merged. You can create two relationships, and have a (hybrid) property which would combine both, but this will only be for reading purposes, as when you would like to modify this property (for example, add
Transits
), you would still need to specify both sides (start
andend
). - I am not sure I understand the question here
update-1: as requested in comment, Concrete-Table inheritance code below:
class Zone(Entity):
__mapper_args__ = {'polymorphic_identity': 'zones'}
__tablename__ = "zones"
id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
@property
def transits(self):
return self.transits_from_here + self.transits_to_here
class Transit(Base):
__tablename__ = "transits"
id = Column(Integer, primary_key=True)
start = Column(Integer, ForeignKey('zones.id'))
end = Column(Integer, ForeignKey('zones.id'))
s_zone = relationship(Zone, primaryjoin=(start==Zone.id), backref="transits_from_here")
e_zone = relationship(Zone, primaryjoin=(end==Zone.id), backref="transits_to_here")
Не связан с StackOverflow