0

我有两个类,标签和硬件,用简单的父子关系定义(见最后的完整定义)。

现在我想通过attribute_mapped_collection使用硬件中的版本字段过滤标签查询,例如:

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: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Tag.hardware has an attribute 'baseband

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

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

我可以这样做:

query = query.filter(Tag.hardware.any(artefact=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)
4

1 回答 1

1

当您编写查询时,我们最终会编写 SQL。您认为从诸如 的表达式会呈现什么 SQL filter(Tag.hardware.baseband)?对此没有简单的答案,SQLAlchemy 从来没有猜测过像这样沿着多条路径遍历是如何工作的。的使用attribute_mapped_collection仅与在 Python 中对对象的操作相关,并且对如何为该属性呈现 SQL 没有影响。因此,您需要使用直接映射到 SQL 的构造,在这种情况下, ANY() 似乎是一个不错的选择。

于 2013-11-15T17:46:53.717 回答