【问题标题】:SQLAlchemy ORM - 3-some object relationshipsSQLAlchemy ORM - 3-一些对象关系
【发布时间】:2020-05-16 06:01:29
【问题描述】:

我将 SQLAlchemy 与 Postgres 一起使用。
来自https://auth0.com/blog/sqlalchemy-orm-tutorial-for-python-developers/的代码示例

我有 3 个对象:

  • 演员
  • 特技演员
  • 联系方式

在原始代码示例中,关系如下:

  • 演员:ContactDetails = 1:0..*
  • 演员:特技演员 = 1:1

查看代码:

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")

我正在努力将此模型扩展到以下关系:

  • 演员:ContactDetails = 1:0..*
  • 演员:特技演员 = 1:1
  • Stuntman:ContactDetails = 1:0..*

特技演员也很努力,值得拥有联系方式。谁能帮忙?!

【问题讨论】:

  • 一种可能性是从ContactDetails 中删除actor_id,并添加将ContactDetails 连接到ActorStuntman 的关联表。
  • 感谢@IljaEverilä。这与 Cysio 的解决方案相同,详见下文。

标签: python postgresql orm sqlalchemy


【解决方案1】:

在我看来,实现所需的最佳方法是使用关联表。这个应该可以工作:

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)

如果你愿意,你可以像这样把unique=True放到关联表中

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)
)

其他选项是在Stuntman 表上放置另一个可为空的外键,但我会采用上面介绍的解决方案。

【讨论】:

  • 这很有意义,而且效果很好。谢谢你!
猜你喜欢
  • 2014-10-13
  • 2020-11-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 2015-04-29
  • 2021-09-18
相关资源
最近更新 更多