![](/img/trans.png)
[英]Bidirectional many-to-many attribute_mapped_collection, sqlalchemy
[英]Filtering SQLAlchemy query on attribute_mapped_collection field of relationship
我有兩個類,Tag和Hardware,它們通過簡單的父子關系定義(請參閱最后的完整定義)。
現在,我想通過attribute_mapped_collection在Hardware中使用version字段對Tag進行查詢,例如:
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)
當您組成查詢時,我們最終將組成SQL。 您認為將從filter(Tag.hardware.baseband)
這樣的表達式中呈現什么SQL? 沒有一個簡單的答案,SQLAlchemy永遠不會猜測如何沿着這樣的多個路徑進行遍歷。 attribute_mapped_collection
的用法僅與對象中的Python操作有關,而對於此屬性的SQL呈現方式沒有影響。 因此,您需要使用直接映射到SQL的結構,在這種情況下,ANY()似乎是一個不錯的選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.