SQLAlchemy 1.X升级至2.X后add_entity报错,如何修复?
SQLAlchemy 2.X中
add_entity结合join字符串参数报错的问题及修复 问题背景
模型定义(models.py)
Base = declarative_base() class Service(Base): __tablename__ = 'Service' id = Column('ID', primary_key=True) f_Service_type_id = Column('f_ServiceTypeID', Integer) sType = relationship('ServiceType', primaryjoin="Service.f_Service_type_id == ServiceType.id", foreign_keys="[Service.f_Service_type_id]") class ServiceType(Base): __tablename__ = 'ServiceType' id = Column("ID", Integer, primary_key=True) name = Column("Name", String(100)) class Services2Produkt(Base): __tablename__ = 'services2produkt' service_id = Column("service_id", Integer, primary_key=True) service = relationship('Service', primaryjoin="Services2Produkt.service_id == Service.id", foreign_keys="[Services2Produkt.service_id]" )
SQLAlchemy 1.X可正常运行的代码
def get_services_of_product(): query = session.query(Services2Produkt) query = query.add_entity(Service).join("service", "sType") return [service for (s2p, service) in query.all()]
升级到2.X后的错误
sqlalchemy.exc.ArgumentError: Join target, typically a FROM expression, or ORM relationship attribute expected, got 'service'.
原因分析
SQLAlchemy 2.X对join()方法的参数校验做了严格收紧,不再支持传入字符串形式的关系名称。1.X版本中,join("service")会被自动解析为当前查询实体(Services2Produkt)的service关系,但2.X要求必须直接传入ORM关系属性对象,不能用字符串间接指代。
修复方案
把join()中的字符串参数替换为对应的实体类关系属性即可,同时可以优化查询逻辑让代码更简洁:
修复后的代码(两种写法)
# 写法1:保留原有add_entity逻辑,替换join参数 def get_services_of_product(): query = session.query(Services2Produkt) query = query.add_entity(Service).join(Services2Produkt.service, Service.sType) return [service for (s2p, service) in query.all()] # 写法2:更简洁的直接查询方式(推荐) def get_services_of_product(): query = session.query(Service).join(Services2Produkt).join(Service.sType) return query.all()
说明
- 用
Services2Produkt.service替代原字符串"service",明确指定要关联的关系属性;同理用Service.sType替代"serviceType" - 推荐的简洁写法直接以
Service为查询目标,通过关联表Services2Produkt完成join,结果直接返回Service实例,无需再解构元组
内容的提问来源于stack exchange,提问作者saromba
相关产品推荐
相关产品推荐

