2013-10-30 35 views
4

我一直想弄清楚如何將request.args傳遞給sqlalchemy過濾器。燒瓶 - 將request.args轉換爲字典

我想這應該工作:

model.query.filter(**request.args).all() 

但它引發錯誤:

TypeError: <lambda>() got an unexpected keyword argument 'userid' 

當用戶ID或任何其他GET ARG存在。

根據這篇文章 - https://stackoverflow.com/questions/19506105/flask-sqlalchemy-query-with-keyword-as-variable - 你可以傳遞一個字典到過濾器函數。

任何想法我做錯了什麼?

非常感謝:)

UPDATE:非常感謝下面的海報,但是現在它拋出以下錯誤:

ProgrammingError: (ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY tblclients.clientname' at line 3") 'SELECT favourites.id AS favourites_id, favourites.userid AS favourites_userid, favourites.clientid AS favourites_clientid, favourites.last_visit AS favourites_last_visit \nFROM favourites INNER JOIN tblclients ON tblclients.clientid = favourites.clientid \nWHERE favourites.userid = %s ORDER BY tblclients.clientname' ([u'41'],) 

任何想法?

回答

3

使用filter_by

model.query.filter_by(**request.args).all() 

filter使用這樣的:query.filter(Class.property == value)filter_by使用這樣的:query.filter_by(property=value)(第一個是一個表達式,後者一個是關鍵字參數)。

5

首先,你必須使用filter_by而不是過濾器。

其次,Flask request.args使用MultiDict,這是一個帶有列表內值的字典,允許同一個鍵有多個值,因爲同一個字段在查詢字符串中可能會出現多次。你得到了錯誤,因爲SQL查詢只有'41'時纔會得到[u'41']。您可以使用request.args.to_dict()來解決這個問題:

model.query.filter_by(**request.args.to_dict()).all() 
+2

這是正確的答案。並且增加它:使用'request.args.to_dict()'是正確的,而'dict(request.args)'不是因爲它會產生一個字典,其值由列表組成。 – Kazanz

0

filter_by(**request.args)如果您有非模型查詢參數,如page爲分頁不能很好地工作,否則你會得到錯誤這樣的:

InvalidRequestError: Entity '<class 'flask_sqlalchemy.JobSerializable'>' has no property 'page' 

我用這樣的事情而忽略查詢參數不是模型:

builder = MyModel.query 
    for key in request.args: 
     if hasattr(MyModel, key): 
      vals = request.args.getlist(key) # one or many 
      builder = builder.filter(getattr(MyModel, key).in_(vals)) 
    if not 'page' in request.args: 
     resources = builder.all() 
    else: 
     resources = builder.paginate(
      int(request.args['page'])).items 

考慮到與一個名爲列模型,像這樣將工作:

curl -XGET "http://0.0.0.0/mymodel_endpoint?page=1&valid=2&invalid=whatever&valid=1" 

invalid將被忽略,並且page可用於分頁和最重要的是,下面的SQL將產生:WHERE mymodel.valid in (1,2)

(得到上面的代碼段免費如果使用boilerplate-saving module