Reputation: 75
I'm using SQLAlchemy with Postgres.
Code example from https://auth0.com/blog/sqlalchemy-orm-tutorial-for-python-developers/
I have 3 objects:
In the original code example, the relationships are as follow:
See Code:
class Actor(Base):
__tablename__ = 'actors'
id = Column(Integer, primary_key=True)
name = Column(String)
birthday = Column(Date)
class Stuntman(Base):
__tablename__ = 'stuntmen'
id = Column(Integer, primary_key=True)
name = Column(String)
active = Column(Boolean)
actor_id = Column(Integer, ForeignKey('actors.id'))
actor = relationship("Actor", backref=backref("stuntman", uselist=False))
class ContactDetails(Base):
__tablename__ = 'contact_details'
id = Column(Integer, primary_key=True)
phone_number = Column(String)
address = Column(String)
actor_id = Column(Integer, ForeignKey('actors.id'))
actor = relationship("Actor")
I'm struggling to extend this model to following relationships:
Stuntmen work hard too and deserve ContactDetails. Who can help please?!
Upvotes: 0
Views: 88
Reputation: 53
In my opinion best way to achieve what you need is using association table. This one should work:
actors_to_contact_details = Table('actors_to_contact_details', Base.metadata,
Column('actor_id', Integer, ForeignKey('actors.id')),
Column('contact_detail_id', Integer, ForeignKey('contact_details.id'))
)
stuntmen_to_contact_details = Table('stuntmen_to_contact_details', Base.metadata,
Column('stuntman_id', Integer, ForeignKey('stuntmen.id')),
Column('contact_detail_id', Integer, ForeignKey('contact_details.id'))
)
class Actor(Base):
__tablename__ = 'actors'
id = Column(Integer, primary_key=True)
name = Column(String)
birthday = Column(Date)
contact_details = relationship("ContactDetails", secondary=actors_to_contact_details)
class Stuntman(Base):
__tablename__ = 'stuntmen'
id = Column(Integer, primary_key=True)
name = Column(String)
active = Column(Boolean)
actor_id = Column(Integer, ForeignKey('actors.id'))
actor = relationship("Actor", backref=backref("stuntman", uselist=False))
contact_details = relationship("ContactDetails", backref="stuntman", secondary=stuntmen_to_contact_details)
class ContactDetails(Base):
__tablename__ = 'contact_details'
id = Column(Integer, primary_key=True)
phone_number = Column(String)
address = Column(String)
if you want, you can put unique=True
in association table like this
actors_to_contact_details = Table('actors_to_contact_details', Base.metadata,
Column('actor_id', Integer, ForeignKey('actors.id')),
Column('contact_detail_id', Integer, ForeignKey('contact_details.id'), unique=True)
)
stuntmen_to_contact_details = Table('stuntmen_to_contact_details', Base.metadata,
Column('stuntman_id', Integer, ForeignKey('stuntmen.id')),
Column('contact_detail_id', Integer, ForeignKey('contact_details.id'), unique=True)
)
Other option would be to put another nullable foreign key on Stuntman
table, but I would go with solution presented above.
Upvotes: 1