使用 python3/Django 1.7 执行原始 SQL
Executing raw SQL with python3/Django 1.7
我正在使用 simple_history,因为我需要模型的历史数据。
我有一个名为 po_staff 的模型,它有一个名为 pool_historicalpo_staff 的 "historical" 模型。
现在我想得到一个基于 pool_historicalpo_staff 的查询集,其中包含每个员工的最后一条记录(我试图让它尽可能简单,因为真正的查询要复杂得多)。
我目前正在 SQLLite
历史模型包含以下数据:
ID staff_nr valid staff_firstname staff_lastname
1 111 01/01/2014 Firstname1 Lastname1
2 3 01/01/2014 Firstname2 Lastname2
2 3 01/04/2014 Firstname2 Lastname2_new #Employee has changed his Lastname
这段代码工作正常(按字母顺序排列):
qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY staff_name, staff_surname ',
[client_id, company_id])
我必须使用"id"进行分组,因为staff_nr可以从用户更改(但它仍然是同一个员工)。
问题 1:
用户可以选择字母顺序和 staff_id
之间的结果顺序
为了实现这一点,我向查询添加了第三个参数:
if order == 1:
order_by = "staff_name, staff_surname"
else:
order_by = "staff_nr"
qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY %s ',
[client_id, company_id, order_by])
查询有效,但不是按字母顺序排列,而是按 "id" 排序。
问题 2:
也必须为其他模型执行查询。只是模型和 order_by 会有所不同。
我不想为每个模型编写几乎相同的查询,因此我试图让它更灵活:
model = .... # instance of current model
order_by = .... # gets the choosen order for current model, p.e. "staff_name, staff_surname"
model_name = .... # gets the model name, p.e. "pool_historicalpo_staff"
qs = model.history.raw ('SELECT * FROM %s '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY %s ',
[model_name, client_id, company_id, order_by])
执行此查询时出错:
Request Method: GET
Request URL: http://127.0.0.1:8000/framework/21/?view=kanban
Django Version: 1.7
Exception Type: OperationalError
Exception Value: near "?": syntax error
Exception Location: c:\python34\lib\site-packages\django\db\backends\sqlite3\base.py in
execute, line 485
Python Executable: c:\python34\python.EXE
Python Version: 3.4.0
希望我解释清楚了。
我是 django 的新手,那是我的第一个原始 SQL
非常感谢您的帮助!
这似乎类似于 Django: MySQL syntax error when passing parameters to raw SQL query
简答:您只能将参数传递给查询。要支持替换部分 SQL 语法,如 table 名称,您需要分两次构建查询,仅在第二次传递中将实际参数传递给查询。
希望对您有所帮助。
我正在使用 simple_history,因为我需要模型的历史数据。 我有一个名为 po_staff 的模型,它有一个名为 pool_historicalpo_staff 的 "historical" 模型。 现在我想得到一个基于 pool_historicalpo_staff 的查询集,其中包含每个员工的最后一条记录(我试图让它尽可能简单,因为真正的查询要复杂得多)。 我目前正在 SQLLite
历史模型包含以下数据:
ID staff_nr valid staff_firstname staff_lastname
1 111 01/01/2014 Firstname1 Lastname1
2 3 01/01/2014 Firstname2 Lastname2
2 3 01/04/2014 Firstname2 Lastname2_new #Employee has changed his Lastname
这段代码工作正常(按字母顺序排列):
qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY staff_name, staff_surname ',
[client_id, company_id])
我必须使用"id"进行分组,因为staff_nr可以从用户更改(但它仍然是同一个员工)。
问题 1: 用户可以选择字母顺序和 staff_id
之间的结果顺序为了实现这一点,我向查询添加了第三个参数:
if order == 1:
order_by = "staff_name, staff_surname"
else:
order_by = "staff_nr"
qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY %s ',
[client_id, company_id, order_by])
查询有效,但不是按字母顺序排列,而是按 "id" 排序。
问题 2: 也必须为其他模型执行查询。只是模型和 order_by 会有所不同。 我不想为每个模型编写几乎相同的查询,因此我试图让它更灵活:
model = .... # instance of current model
order_by = .... # gets the choosen order for current model, p.e. "staff_name, staff_surname"
model_name = .... # gets the model name, p.e. "pool_historicalpo_staff"
qs = model.history.raw ('SELECT * FROM %s '
'WHERE clientID_id is %s and companyID_id is %s '
'GROUP BY id '
'ORDER BY %s ',
[model_name, client_id, company_id, order_by])
执行此查询时出错:
Request Method: GET
Request URL: http://127.0.0.1:8000/framework/21/?view=kanban
Django Version: 1.7
Exception Type: OperationalError
Exception Value: near "?": syntax error
Exception Location: c:\python34\lib\site-packages\django\db\backends\sqlite3\base.py in
execute, line 485
Python Executable: c:\python34\python.EXE
Python Version: 3.4.0
希望我解释清楚了。 我是 django 的新手,那是我的第一个原始 SQL
非常感谢您的帮助!
这似乎类似于 Django: MySQL syntax error when passing parameters to raw SQL query
简答:您只能将参数传递给查询。要支持替换部分 SQL 语法,如 table 名称,您需要分两次构建查询,仅在第二次传递中将实际参数传递给查询。
希望对您有所帮助。