如何在SQLAlchemy中使用数学方程作为过滤器

3 投票
2 回答
6707 浏览
提问于 2025-04-15 17:38

我在我的应用程序中使用SQLAlchemy这个工具来构建MySQL查询,基本的过滤条件我已经能轻松添加,比如这样:

query = meta.Session.query(User).filter(User.user_id==1)

这基本上等同于下面这个:

SELECT * FROM users WHERE user_id = 1

我想问的是,如何在我的查询中加入一些基本的MySQL数学函数。比如说,我想找出靠近某个经纬度的用户。那么我需要生成这样的SQL($mylatitude和$mylongitude是我用来比较的固定经纬度):

SELECT * FROM users 
WHERE SQRT(POW(69.1 * (latitude - $mylatitude),2) + POW(53.0 * (longitude - $mylongitude),2)) < 5

有没有办法可以在使用SQLAlchemy这个工具时,把这些函数整合进查询里呢?

2 个回答

6

你可以在你的筛选条件中使用直接的SQL语句,具体可以参考这里:http://www.sqlalchemy.org/docs/05/ormtutorial.html?highlight=text#using-literal-sql

举个例子:

clause = "SQRT(POW(69.1 * (latitude - :lat),2) + POW(53.0 * (longitude - :long),2)) < 5"
query = meta.Session.query(User).filter(clause).params(lat=my_latitude, long=my_longitude)
4

我会使用查询构建器接口和func这个SQL函数构造器,把计算过程抽象成一个函数。这样你就可以随意使用它,比如在别名或者连接查询中。

User.coords = classmethod(lambda s: (s.latitude, s.longitude))

def calc_distance(latlong1, latlong2):
    return func.sqrt(func.pow(69.1 * (latlong1[0] - latlong2[0]),2)
                   + func.pow(53.0 * (latlong1[1] - latlong2[1]),2))

meta.Session.query(User).filter(calc_distance(User.coords(), (my_lat, my_long)) < 5)

撰写回答