SQLAlchemy操作MySQL关联表无法存储及读取重复关联项问题
问题根因
你遇到的现象是SQLAlchemy默认多对多关系的设计逻辑导致的,不是操作失误也不是数据库配置问题:
- 默认通过
secondary参数配置的多对多关系采用集合去重语义,关联对象列表默认会自动去重,哪怕你往列表里重复添加同一个对象,ORM也只会保留一份,提交时只会生成1条关联记录。 - 读取数据时,默认多对多查询会自动按
MembershipType的主键去重,所以哪怕你手动往关联表插入了多条相同外键的记录,ORM也只会返回1个对应的MembershipType对象。
解决方案
因为你的关联表本身带有独立主键ID,适合采用关联对象模式改造关联配置,即可支持重复关联的存储和读取:
- 首先定义关联表对应的独立ORM类
from sqlalchemy import Column, Integer, ForeignKey from sqlalchemy.orm import relationship # 导入你项目中的ORM基类Base from your_base_file import Base class MembershipMembershipTypeRel(Base): __tablename__ = 'associationtable_membership_membershiptypes' ID = Column(Integer, primary_key=True, autoincrement=True) MembershipID = Column(Integer, ForeignKey('memberships.ID')) MembershipTypeID = Column(Integer, ForeignKey('membershiptypes.ID')) # 关联到会员类型表 membership_type = relationship("MembershipType", lazy="joined")
- 修改Membership类的关联配置,把原来的多对多关系改为和关联类的一对多关系
class Membership(Base): __tablename__ = 'memberships' # 保留原有所有字段定义 ID = Column(Integer, primary_key=True, autoincrement=True) # 其他原有字段... # 关联到中间表的一对多关系 type_relations = relationship("MembershipMembershipTypeRel", cascade="all, delete-orphan") # 兼容原有listMembershipTypeObjects属性的调用逻辑 @property def listMembershipTypeObjects(self): return [rel.membership_type for rel in self.type_relations]
- 调整添加关联的代码逻辑
# 假设已经获取到membership实例、silver会员类型实例 # 需要添加几次就生成几个中间表实例即可 rel1 = MembershipMembershipTypeRel(membership_type=silver) rel2 = MembershipMembershipTypeRel(membership_type=silver) membership.type_relations.extend([rel1, rel2]) # 提交后即可在关联表生成两条记录,读取时listMembershipTypeObjects也会返回两个silver对象
内容的提问来源于stack exchange,提问作者TheFaithfulLearner
相关产品推荐
相关产品推荐

