如何构建一个sqlalchemy查询,其中包含带有@>的过滤器运营商?

时间:2016-05-02 15:14:06

标签: python sqlalchemy

我有以下工作的flask / sqlalchemy查询:

paged_data = House.query\
    .with_entities(
        House.name,
        db.func.earth_distance(
            db.func.ll_to_earth(current_latitude, current_longitude),
            House.earth_location
        ).label('house_distance_from_current_location')
    )\
    .filter(db.text('earth_box(ll_to_earth(:latitude, :longitude), :radius)'
                    ' @> ll_to_earth(houses.latitude, houses.longitude)'
                   )
    )\
    .params(latitude=latitude, longitude=longitude, radius=radius)\
    .all()

但我更喜欢清理它看起来更像下面的代码......显然它不会那样工作......但我无法弄清楚如何写它...特别是,使用@>运算符与>运算符一样无效的Python。

paged_data = House.query\
    .with_entities(
        House.name,
        db.func.earth_distance(
            db.func.ll_to_earth(current_latitude, current_longitude),
            House.earth_location
        ).label('house_distance_from_current_location')
    )\
    .filter(
        db.func.earth_box(db.func.ll_to_earth(current_latitude, current_longitude), radius) @> House.earth_location
    )\
    .params(latitude=latitude, longitude=longitude, radius=radius)\
    .all()

有没有办法做到这一点,或者我只需要使用text()来解决?

此处参考的是House模型(它使用create_materialized_view()函数可以正常工作):

class House(db.Model):
    __table__ = create_materialized_view(
        'houses',
        db.select([
            House.id.label('id'),
            House.name.label('name'),
            House.latitude.label('latitude'),
            House.longitude.label('longitude'),
            db.func.ll_to_earth(House.latitude, House.longitude).label('earth_location'),
        ]).where(
            db.and_(
                House.reviewed == True,
                House.deleted == False
            )
        )
    )

1 个答案:

答案 0 :(得分:3)

您需要op方法

.filter(
    db.func.earth_box(db.func.ll_to_earth(current_latitude, current_longitude), radius)
    .op('@>')(House.earth_location)
)