【问题标题】:SQLAlchemy ORM search through multiple relationships for an attributeSQLAlchemy ORM 搜索属性的多个关系
【发布时间】:2018-06-17 12:12:22
【问题描述】:

我知道可以通过关系属性过滤初始查询(请参阅SqlAlchemy - Filtering by Relationship Attribute

但是在你已经检索到对象之后呢?

给定:

class Parks(Base):
    __tablename__ = 'parks'

    id = Column(Integer, primary_key=True)
    description = Column(String, nullable=False, unique=True, index=True)
    state = Column(String(2))
    city = Column(String)
    zipcode = Column(String, index=True)

    alerts = relationship('Alerts', back_populates='park')


class Alerts(Base):
    __tablename__ = 'alerts'

    id = Column(Integer, primary_key=True)
    park_id = Column(Integer, ForeignKey('parks.id'))
    alert_type_id = Column(Integer, ForeignKey('alert_types.id'))
    alert_message = Column(String)

    park = relationship('Parks', back_populates="alerts")
    alert_type = relationship('AlertTypes', back_populates='alerts')


class AlertTypes(Base):
    __tablename__ = 'alert_types'

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

    alerts = relationship('Alerts', back_populates='alert_type')

我知道我能做到

park_closed_alert = session.query(AlertTypes)\
    .filter(AlertTypes.alert_type_long_des == 'Park Closed').first()

closed_parks = session.query(Parks)\
    .filter(Parks.alerts.any(alert_type = park_closed_alert )).all()

获取所有已关闭公园的列表...

但是如果我已经检索了一个特定的公园,然后我想查看它是否已关闭,该怎么办?或者查看是否存在针对特定条件的多个警报(关系)。

park_record_from_db = session.query(Parks).filter(Parks.longdes == 'City Park').first()

park_record_from_db.alerts 会给我一个警报列表,我可以轻松地遍历它们...但是由于调用.alerts 关系无论如何都会再次查询数据库,我可以只传递过滤器吗?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    这可以通过dynamic relationship loaders 完成。定义关系时指定lazy=dynamic。然后该属性将表现为Query 对象,可以过滤而不是立即加载。

    alerts = relationship('Alerts', back_populates='park', lazy='dynamic')
    [...]
    filtered_alerts = park_record_from_db.alerts.filter( \
        Alerts.alert_type.in_((park_closed_alert, park_dogs_alert))).all()
    

    另一个选项是query-enabled properties,它允许更多的自定义。

    当然,如果你想在检索初始对象的时候按关系过滤,可以使用any操作符:

    park_record_from_db = session.query(Parks) \
        .filter(Parks.longdes == 'City Park') \
        .filter(Parks.alerts.any( \
            Alerts.alert_type.in_((park_closed_alert, park_dogs_alert)))) \
        .first()
    

    【讨论】:

      猜你喜欢
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 2015-04-11
      • 1970-01-01
      • 2012-10-27
      • 2016-12-03
      • 2013-01-10
      相关资源
      最近更新 更多