2010-01-04 101 views
2

我使用SQLAlchemy的ORM來構建我的應用程序MySQL的查詢,我完全能夠基本過濾器添加到查詢,如下所示:如何使用數學方程式過濾器在SQLAlchemy的

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的ORM的查詢?

回答

2

我會使用查詢生成器界面和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) 
+1

Can 't得到這個工作,似乎's.latitude'和's.longitude'返回類方法的經度和緯度,而不是實例的經度和緯度。不知道我在做什麼錯誤... – ken 2015-07-16 02:20:20

4

您可以使用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) 
+0

這就是我正在尋找的。但有一個問題:如果我加入一堆其他表格,我如何確保緯度與User.latitude匹配,而不是其他緯度字段?由於我的User對象可能鏈接到實際查詢中的一個名爲xx_users_1的表,有沒有辦法將表名「xx_users_1'.'latitude'? – Travis 2010-01-04 21:59:26

+0

你可以嘗試使用'sqlalchemy.orm.aliased'強制表名(可能類似於'query(aliased(User,'xx_users'))'',但我從來沒有用過它。 – 2010-01-05 11:43:38

相關問題