Django似乎错误地声称我的SQL语法有错误。查询在django dbshell中运行正常(返回预期结果),但在通过Django运行查询时会产生错误。这是代码(跟踪追溯):
#this code is inside the models.Customer.display_sharers() function
sharers_by_action_count = Sharer.objects.raw('''
SELECT wordout_sharer.id, COUNT(actions_of_type.id) AS action_count
FROM
wordout_customer
INNER JOIN wordout_sharer
ON wordout_sharer.customer_id = wordout_customer.id
LEFT JOIN wordout_click
ON wordout_sharer.id = wordout_click.sharer_id
LEFT JOIN
(SELECT wordout_action.id, wordout_action.click_id
FROM wordout_action
WHERE
wordout_action.action_type_id = %s) as actions_of_type
ON actions_of_type.click_id = wordout_click.id
WHERE wordout_customer.id = %s
GROUP BY wordout_sharer.id
ORDER BY action_count %s
''', (action_type_id, self.id, direction))
force_execution = list(sharers_by_action_count) #force the query to run by converting it to a list.. this is to trigger the error.
这是追溯:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/me/sources/django_wordout/../django_wordout/wordout/models.py", line 106, in display_sharers
if order_by == 'action_count': #we have to make a special query for when they want to sort by the count of a specific action
File "/Users/me/sources/django_wordout/../django_wordout/wordout/models.py", line 92, in sharers_by_action_count_with_total_clicks
force_exec = list(sharers_by_action_count)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 1324, in __iter__
query = iter(self.query)
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 67, in __iter__
self._execute_query()
File "/Library/Python/2.7/site-packages/django/db/models/sql/query.py", line 81, in _execute_query
self.cursor.execute(self.sql, self.params)
File "/Library/Python/2.7/site-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/Library/Python/2.7/site-packages/django/db/backends/sqlite3/base.py", line 234, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: near "?": syntax error
执行Database.Cursor.execute(self, query, params)
时,以下是所有参数的值:
自我:
<django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x10c477180>
查询:
SELECT wordout_sharer.id, COUNT(actions_of_type.id) AS action_count
FROM
wordout_customer
INNER JOIN wordout_sharer
ON wordout_sharer.customer_id = wordout_customer.id
LEFT JOIN wordout_click
ON wordout_sharer.id = wordout_click.sharer_id
LEFT JOIN
(SELECT wordout_action.id, wordout_action.click_id
FROM wordout_action
WHERE
wordout_action.action_type_id = ?) as actions_of_type
ON actions_of_type.click_id = wordout_click.id
WHERE wordout_customer.id = ?
GROUP BY wordout_sharer.id
ORDER BY action_count ?
PARAMS:
(1, 1, 'DESC')
我在Django中发现了一个错误吗?它是否无法正确处理某些类型的查询?
我的配置:我正在运行一个漂亮的vanilla开发配置。对于db引擎,我使用的是sqlite。对于迁移(这是最新的),我正在使用South。
刚刚发现用%s
替换它们的值会使查询起作用..怎样才能使%s
对Django有问题?
答案 0 :(得分:4)
According to this page,sqlite将参数化值视为文字,这意味着它们插入给定类型的常量,而不是执行常规的“文本替换”。
由于order by中的ASC或DESC是关键字,而不是常量,因此不能用参数替换。
如果你做了
,这实际上会产生一些可能出乎意料的行为ORDER BY ? DESC
并且你给它一个列名(比如column1),它实际上运行但没有按你预期的顺序排序。原因是它实际上按字符串“column1”排序 - 对于每一行都是相同的 - 而不是实际的列内容。
答案 1 :(得分:0)
我发现自己处于类似情况。在我们的两种情况下,我们都是通过不使用字符串格式化来正确地做事:
Database.Cursor.execute(self, query, params)
但是,如果你绝对信任你的输入(即它们是系统提供的,而不是用户提供的),我发现我可以通过危险的方式做事来绕过这个错误:
Database.Cursor.execute(self, query % tuple(params))
对于未来的读者:请注意,如果您将此作为解决方法使用,则会使您容易受到SQL注入攻击。如果您不明白这意味着什么,请不要这样做!