python - 链中存在多个一对多映射的长链存在查询

标签 python postgresql sqlalchemy

编辑:以下片段似乎是正确的方法: session.query(User).join("userGadgets", "gadget", "components","gadgetComponentMetals")

原创: 我配置了下表:

class User(Base):
    __tablename__ = "user"

    id = Column(Integer, primary_key=True)
    name = Column(String)


class Gadget(Base):
    __tablename__ = "gadget"

    id = Column(Integer, primary_key=True)
    brand = Column(String)


class UserGadget(Base):
    __tablename__ = "user_gadget"

    user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
    gadget_id = Column(Integer, ForeignKey('gadget.id'), primary_key=True)

    user = relationship("User", backref=backref('userGadgets', order_by=user_id))
    gadget = relationship("Gadget", backref=backref('userGadgets', order_by=gadget_id))


class GadgetComponent(Base):
    __tablename__ = "gadget_component"

    id = Column(String, primary_key=True)
    gadget_id = Column(Integer,ForeignKey('gadget.id'))
    component_maker = Column(String)

    host = relationship("Gadget", backref=backref('components', order_by=id))


class ComponentUsingMetal(Base):
    __tablename__ = "component_metal"

    id = Column(Integer, primary_key=True)    
    component_id = Column(Integer, ForeignKey('GadgetComponent.id'))  
    metal = Column(String)

    component = relationship("GadgetComponent", backref=backref('gadgetComponentMetals', order_by=id))

我想查找拥有至少一个组件包含某种金属的小工具的用户的所有用户名。对此的 SQL 查询类似于:

SELECT distinct u.name FROM user u join user_gadget ug on (u.id = ug.user_id) join gadget_component gc on (ug.gadget_id = gc.id) join component_metal cm on (gc.id = cm.component_id) order by u.name

我尝试了各种版本:session.query(User).filter(User.userGadgets.any(UserGadget.gadget.components.any(GadgetComponent.gadgetComponentMetals.exists())))

我收到以下错误: AttributeError:与 UserGadget.gadget 关联的“InstrumentedAttribute”对象和“Comparator”对象都没有属性“gadgetComponents”

关于我做错了什么的任何想法,或者是否有更好的方法在 SQLAlchemy 中执行此类查询?

最佳答案

join() 是更好的方法,因为 any() 会产生大量昂贵的嵌套子查询。但是您在使用“any”时犯的错误是使用了如下语法:UserGadget.gadget.components。 SQLAlchemy 不会像这样在系列中继续属性的命名空间,例如没有 UserGadget.gadget.components;分别只有 UserGadget.gadgetGadget.components。就像 SQL 不会让你说“SELECT * from user_gadget.gadget_id.gadget.component_id”之类的东西一样,SQLAlchemy 需要你告诉它你想如何将你正在查询的多个表连接在一起。使用 any() 时,它类似于 any(and_(UserGadget.gadget_id == GadgetComponent.gadget_id)),但在任何情况下使用 JOIN 都更好。

关于python - 链中存在多个一对多映射的长链存在查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21230065/

相关文章:

python - 'sdist' .tar.gz 分布和 python 鸡蛋有什么区别?

sql - 在 Postgres 中查找 min + 1

postgresql - 如何在GGST中添加postgresql jar

python - SQLAlchemy 的正确模型定义是什么以避免错误消息 : AttributeError: 'InstrumentedList' object has no attribute'?

python - centos6.9 上的 cassandra 无法连接到服务器

python - 在Python中获取/过滤与属性/键匹配的对象列表中的第一项

python - 如何在 sqlalchemy 中执行 LIKE 查询?

python - WSGI、Werkzeug 和基于表单的身份验证

python - 将两个 matplotlib slider 链接在一起

database - Postgres 目录丢失