栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将复杂的SQL查询转换为SQLAlchemy

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将复杂的SQL查询转换为SQLAlchemy

HAVINg
的处理方式正确,但是您传递的是错误的表达式。似乎您正在使用Python 2,因为字符串和整数之间的关系比较

'distance' < 25

不会引发异常,而是求值为

False
。换句话说,您的查询等于

locations = db.session.query(...).having(False).all()

这就解释了为什么您得到零结果的原因:所有行都被HAVINg子句明确过滤掉了,如印刷版所示:

...HAVINg false = 1  -- remove all rows

一种解决方案是使用合适的构造,例如

column()
,来产生表达式:

locations = db.session.query(...).having(column('distance') < 25).all()

您不应将复杂的选择列表项表达式包装在

select()
表示SELECT语句的中。标签
text()
为:

text('( 6371 * acos( cos( radians("53.6209798282177") ) * '     'cos( radians( lat ) ) * cos( radians( lng ) - radians("13.96948162900808") ) + '     'sin( radians("53.6209798282177") ) * sin( radians( lat ) ) ) ) '     'AS distance')

或使用模型构建表达式:

(6371 * func.acos(func.cos(func.radians(53.6209798282177)) *func.cos(func.radians(Location.lat)) *func.cos(func.radians(Location.lng) - func.radians(13.96948162900808)) +func.sin(func.radians(53.6209798282177)) *func.sin(func.radians(Location.lat)))).label('distance')

你可以通过使功能为提高查询建设的可读性大圆距离,并与工作的一点点,你可以实现一个混合方法上

Location

import mathdef gc_distance(lat1, lng1, lat2, lng2, math=math):    ang = math.acos(math.cos(math.radians(lat1)) *         math.cos(math.radians(lat2)) *         math.cos(math.radians(lng2) -       math.radians(lng1)) +         math.sin(math.radians(lat1)) *         math.sin(math.radians(lat2)))    return 6371 * angclass Location(db.Model):    ...    @hybrid_method    def distance(self, lat, lng):        return gc_distance(lat, lng, self.lat, self.lng)    @distance.expression    def distance(cls, lat, lng):        return gc_distance(lat, lng, cls.lat, cls.lng, math=func)locations = db.session.query(        Location,        Location.distance(53.6209798282177,    13.96948162900808).label('distance')).    having(column('distance') < 25).    order_by('distance').    all()

请注意,使用HAVINg消除非组行的方法不是可移植的。例如,在Postgresql中,即使没有GROUP
BY子句,HAVINg子句的存在也会将查询转换为分组查询。您可以改用子查询:

stmt = db.session.query(        Location,        Location.distance(53.6209798282177,    13.96948162900808).label('distance')).    subquery()location_alias = db.aliased(Location, stmt)locations = db.session.query(location_alias).    filter(stmt.c.distance < 25).    order_by(stmt.c.distance).    all()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/668491.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号