0

Tag と Hardware という 2 つのクラスがあり、単純な親子関係で定義されています (完全な定義は最後を参照してください)。

ここで、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 に答える