1. 程式人生 > 實用技巧 >Django model層之執行原始SQL查詢

Django model層之執行原始SQL查詢

Django model層之執行原始SQL查詢

by:授客 QQ1033553122

測試環境

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

serializers

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__)