SQLAlchemy ORM模型扩展:为Stuntman添加ContactDetails关联
完全理解!特技演员确实需要自己的联系方式,毕竟工作这么辛苦~咱们来调整SQLAlchemy模型实现这个需求,以下是修改后的完整代码和关键说明:
修改后的模型定义
from sqlalchemy import Column, Integer, String, Date, Boolean, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, backref Base = declarative_base() class Actor(Base): __tablename__ = "actors" id = Column(Integer, primary_key=True) name = Column(String) birthday = Column(Date) # 保留原有的1:0..*演员联系方式关联,明确指定外键避免混淆 contact_details = relationship( "ContactDetails", backref="actor", foreign_keys="[ContactDetails.actor_id]" ) # 保留原有的1:1特技演员关联 stuntman = relationship("Stuntman", backref=backref("actor", uselist=False)) class Stuntman(Base): __tablename__ = "stuntmen" id = Column(Integer, primary_key=True) name = Column(String) active = Column(Boolean) actor_id = Column(Integer, ForeignKey('actors.id')) # 新增:特技演员的1:0..*联系方式关联 contact_details = relationship( "ContactDetails", backref="stuntman", foreign_keys="[ContactDetails.stuntman_id]" ) 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'), nullable=True) # 新增特技演员外键(nullable=True表示一条联系方式可属于演员或特技演员) stuntman_id = Column(Integer, ForeignKey('stuntmen.id'), nullable=True)
关键改动说明
- ContactDetails扩展:新增
stuntman_id外键并设为nullable=True,这样一条联系方式可以属于演员、特技演员,或者暂时不关联任何对象(根据业务需求调整) - 明确关联外键:因为ContactDetails现在有两个外键,所以在Actor和Stuntman的
relationship中通过foreign_keys参数指定对应的外键,避免SQLAlchemy混淆关联关系 - 双向关联支持:通过
backref实现反向访问,比如可以直接通过contact.stuntman获取该联系方式所属的特技演员,stuntman.contact_details获取特技演员的所有联系方式
使用示例
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from datetime import date # 初始化数据库连接和会话 engine = create_engine('postgresql://your_user:your_password@localhost/your_db') Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() # 创建演员和特技演员 actor = Actor(name="Tom Cruise", birthday=date(1962, 7, 3)) stuntman = Stuntman(name="Joe Stunt", active=True, actor=actor) session.add_all([actor, stuntman]) session.commit() # 给特技演员添加联系方式 stunt_contact = ContactDetails( phone_number="555-STUNT", address="456 Action Lane", stuntman=stuntman ) session.add(stunt_contact) session.commit() # 查询特技演员的联系方式 target_stuntman = session.query(Stuntman).filter_by(name="Joe Stunt").first() print(f"特技演员 {target_stuntman.name} 的联系方式:{target_stuntman.contact_details[0].phone_number}")
内容的提问来源于stack exchange,提问作者Mark Hallbauer
相关产品推荐
相关产品推荐

