Python 在关系的属性\映射\集合字段上筛选SQLAlchemy查询

Python 在关系的属性\映射\集合字段上筛选SQLAlchemy查询,python,sqlalchemy,Python,Sqlalchemy,我有两个类,Tag和Hardware,它们是用简单的父子关系定义的(参见最后的完整定义) 现在,我想使用硬件中的version字段通过属性映射集合过滤标签查询,例如: def get_tags(order_code=None, hardware_filters=None): session = Session() query = session.query(Tag) if order_code: query = query.filter(Tag.order

我有两个类,Tag和Hardware,它们是用简单的父子关系定义的(参见最后的完整定义)

现在,我想使用硬件中的version字段通过属性映射集合过滤标签查询,例如:

def get_tags(order_code=None, hardware_filters=None):
    session = Session()
    query = session.query(Tag)
    if order_code:
        query = query.filter(Tag.order_code == order_code)
    if hardware_filters:
        for k, v in hardware_filters.iteritems():
            query = query.filter(getattr(Tag.hardware, k).version == v)
    return query.all()
但我得到:

AttributeError:与标记关联的“InstrumentedAttribute”对象和“Comparator”对象都没有属性“baseband”

如果我通过硬编码属性将其剥离,也会发生同样的情况,例如:

query.filter(Tag.hardware.baseband.version==v)

我可以这样做:

query=query.filter(Tag.hardware.any(artifact=k,version=v))

但是为什么我不能直接通过属性过滤呢

类别定义

class Tag(Base):
    __tablename__ = 'tag'
    tag_id = Column(Integer, primary_key=True)
    order_code = Column(String, nullable=False)
    version = Column(String, nullable=False)
    status = Column(String, nullable=False)
    comments = Column(String)
    hardware = relationship(
        "Hardware",
        backref="tag",
        collection_class=attribute_mapped_collection('artefact'),
    )
    __table_args__ = (
        UniqueConstraint('order_code', 'version'),
    )

class Hardware(Base):
    __tablename__ = 'hardware'
    hardware_id = Column(Integer, primary_key=True)
    tag_id = Column(String, ForeignKey('tag.tag_id'))
    product_id = Column(String, nullable=True)
    artefact = Column(String, nullable=False)
    version = Column(String, nullable=False)

当您编写查询时,我们最终编写的是SQL。您认为从表达式(如
filter(Tag.hardware.baseband)
)可以呈现什么样的SQL?这个问题没有简单的答案,SQLAlchemy也从来没有猜测过沿着多条路径进行这样的遍历是如何工作的。
attribute\u mapped\u collection
的使用仅与Python中的对象操作相关,对该属性的SQL呈现方式没有影响。因此,您需要使用直接映射到SQL的构造,在本例中,ANY()似乎是一个不错的选择。

感谢您的解释。我终于意识到你说的是真的;它需要用SQL表示。我最终加入了Join,因为我清楚地理解了他们。因为我对SQLAlchemy和ORM都是新手,所以我仍然对它有感觉。目前,我必须想一想“我该如何用SQL写这个?”然后试着理解SQLAlchemy文档,直到我能做到这一点。我可以看到SQLAlchemy查询如何比Python中基于文本的SQL查询更灵活、更容易组合,但我仍在努力学习。