Django model層之執行原始SQL查詢
Django model層之執行原始SQL查詢
by:授客 QQ:1033553122
測試環境
Win7
Django 1.11
執行原始SQL查詢
Manager.raw
(raw_query,params=None,translations=None)
例子:
from website.models import API_case_tree
sql_for_cases_query = 'SELECT id, creater FROM website_api_case_tree'
query_set = API_case_tree.objects.raw(sql_for_cases_query)
for item in query_set:
print(item.id, item.creater)
說明:
執行raw查詢,查詢列必須包含主鍵id
某次實踐時發現,通過raw執行以下語句,會報錯:not enough arguments for format string
SELECT data_date, group_id as id, groupname AS name
FROM tb_zentao_group_defect_trend_daily_statistics WHERE DATE_FORMAT(data_date,"%Y-%m-%d") >="2019-05-01" AND DATE_FORMAT(data_date,"%Y-%m-%d") <="2019-08-03"
解決方案:格式化引數中的 % 寫成 %%,如下:
SELECT data_date, group_id as id, groupname AS name
FROM tb_zentao_group_defect_trend_daily_statistics WHERE DATE_FORMAT(data_date,"%%Y-%%m-%%d") >="2019-05-01" AND DATE_FORMAT(data_date,"%%Y-%%m-%%d") <="2019-08-03"
序列化
假如想要序列化上述例子中返回的RawQuerySet,可才用以下方式
from django.core import
result = json.loads(serializers.serialize('json', query_set), encoding='utf-8')
如果返回的RawQuerySet為空,則序列化結果result為 [],否則返回類似以下結果
[{'pk': 400, 'model': 'appName. website_api_case_tree, 'fields': {'id': 24, 'creater': '曾龍'}}, {'pk': 401, 'model': 'appName. website_api_case_tree, 'fields': {'id': 24, 'creater': 'x彬'}}]
說明:pk為主鍵,對應資料庫的主鍵id,model為資料表對應的的應用的model,appName為建立的應用的名稱,fields存放查詢的欄位結果
另外,也可以通過fields引數限制 fields欄位值中返回的欄位(需要注意的時,fields中指定的欄位必須時資料庫中存在的欄位,不能是別名)
例子:限制fields中僅返回id和creater欄位
serializers.serialize('json', query_set, fields=('id', 'creater'))
注意:實踐時發現,執行的sql語句關聯表時使用了左連線,發現採用上述方式對結果集進行序列化後,右表中的欄位全部缺失,解決方法如下,通過遍歷獲取對應結果:
query_set = Project.objects.raw(sql)
rows = []
for item in query_rows:
item.__dict__.pop('_state') # 移除不必要的欄位
# 針對datetime、date型別欄位,需要格式化處理,有必要也可以封裝成函式
item.__dict__['create_time'] = item.__dict__['create_time'].strftime('%Y-%m-%d %H:%M:%S')
item.__dict__['update_time'] = item.__dict__['update_time'].strftime('%Y-%m-%d %H:%M:%S')
item.__dict__['begin_time'] = item.__dict__['begin_time'].strftime('%Y-%m-%d')
item.__dict__['end_time'] = item.__dict__['end_time'].strftime('%Y-%m-%d')
rows.append(item.__dict__)