Python 如何在炼金术中使用数学方程作为过滤器

Python 如何在炼金术中使用数学方程作为过滤器,python,mysql,orm,sqlalchemy,Python,Mysql,Orm,Sqlalchemy,我正在使用SQLAlchemy ORM在我的应用程序中构造MySQL查询,并且完全能够向查询添加基本过滤器,如下所示: query = meta.Session.query(User).filter(User.user_id==1) 这给了我一些基本上与之相当的东西: SELECT * FROM users WHERE user_id = 1 我的问题是如何将一些基本的MySQL数学函数集成到查询中。比如说,我想让用户接近某个纬度和经度。所以我需要生成这个SQL($mylatitude和$m

我正在使用SQLAlchemy ORM在我的应用程序中构造MySQL查询,并且完全能够向查询添加基本过滤器,如下所示:

query = meta.Session.query(User).filter(User.user_id==1)
这给了我一些基本上与之相当的东西:

SELECT * FROM users WHERE user_id = 1
我的问题是如何将一些基本的MySQL数学函数集成到查询中。比如说,我想让用户接近某个纬度和经度。所以我需要生成这个SQL($mylatitude和$mylongitude是我比较的静态纬度和经度):

从用户中选择*
式中SQRT(POW(69.1*(纬度-$Mylatude),2)+POW(53.0*(经度-$mylongitude),2))<5

是否有一种方法可以使用SQLAlchemy ORM将这些函数合并到查询中?

您可以在过滤器中使用文字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)
clause=“SQRT(波(69.1*(纬度-:纬度),2)+波(53.0*(经度-:长),2))<5”
query=meta.Session.query(User).filter(子句).params(lat=my_纬度,long=my_经度)

我将使用查询生成器界面和
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)
User.coords=classmethod(lambda s:(s.纬度,s.经度))
def calc_距离(latlong1,latlong2):
返回函数sqrt(函数功率(69.1*(latlong1[0]-latlong2[0]),2)
+函数pow(53.0*(latlong1[1]-latlong2[1]),2))
meta.Session.query(User.filter)(计算距离(User.coords(),(my_lat,my_long))<5)

这正是我要找的。但有一个问题:如果我加入一组其他表,我如何确保纬度与User.latitude匹配,而不是与其他纬度字段匹配?由于我的用户对象在实际查询中可能会链接到一个名为xx_users_1的表,有没有办法将表名
xx_users_1
latitude
?您可以尝试使用
sqlalchemy.orm.aliased
(可能类似于
query(aliased(User,'xx_users'))将表名强制为特定值
。但我从未使用过它。无法实现此功能。似乎
s.latitude
s.latitude
返回类方法的纬度和经度,而不是实例的纬度和经度。不确定我做错了什么。。。
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)