2014-12-02 109 views
1
SELECT * 
FROM product_stocks 
WHERE detected_date = (
         SELECT MAX(detected_date) 
         FROM product_stocks 
         WHERE id = 18865 
        ) 
     AND id = 18865; 

將此轉換爲SQLAlchemy查詢字符串有很多麻煩。什麼是最有效的方法?將原始SQL轉換爲SQLAlchemy查詢

+0

「最有效的方式」是什麼意思?你是否試圖在你甚至知道如何構建它之前優化查詢? – abarnert 2014-12-02 23:03:40

+0

另外,您是使用SQLAlchemy ORM,還是僅使用查詢表達式語言? – abarnert 2014-12-02 23:12:43

回答

2

以下會重新要求您提供的SQL:

_id = 18865 
T = aliased(ProductStock, name="T") 
T1 = aliased(ProductStock, name="T1") 
subquery = (
    session.query(func.max(T1.detected_date).label("detected_date")) 
    .filter(T1.id == _id) 
    # .filter(T1.id == T.id) # @note: i prefer this one to the line above 
    .as_scalar() 
) 
qry = (
    session.query(T) 
    .filter(T.detected_date == subquery) 
    .filter(T.id == _id) 
) 

這是最有效的方式來完成你想要什麼? - 我不敢肯定,但沒有足夠的信息

4

您可以使用from_statement執行原始SQL查詢並在SQL-Alchemy對象中獲取它。這有助於編寫簡單的SQL,然後編寫SQLAlchemy語法。

Session.query(YourClass).from_statement(text('''SELECT * FROM product_stocks 
WHERE detected_date = (SELECT MAX(detected_date) FROM product_stocks WHERE id = 18865) 
AND id = 18865;''')).all() 
+0

你知道如何從傳統的SQLAlchemy做到這一點嗎? – 2017-03-13 20:14:04

+0

長時間沒有使用SQLAlchemy。但據我記憶,這是做到這一點的方法。不知道你的經典SQL鍊金術是什麼意思。但是也許你的意思是一個只替換'Session.query(class)'的特定模型的簡短句柄。休息應該是一樣的。它只是關於你想要綁定數據的對象。但是我可能會錯,因爲我說我很久沒有使用它了。 – muthan 2017-03-13 20:41:26

+0

我想通了,謝謝:http://stackoverflow.com/a/42775416/1391717 – 2017-03-13 23:45:07

0

擁有經典的SQLAlchemy:

 
sql = 'SELECT foo FROM bar' 
sql = text(sql) 
sql = sql.columns() # This let's it be used as a subquery 

sel = select(['foo']).select_from(sql) 
# I needed this for a complex query or else columns would be ambiguous 
sel = sel.alias('sel') 

joined = sel.outerjoin(baz_t, baz_t.foo==sel.foo) 

final = select([sel.c.foo]).select_from(joined) 

注意,columns()是必要的,而且是alias()有益的,如果查詢是複雜的。

以下text文檔很有幫助。