1

问题:django "in" 子句是否要求列表有两个值?

我在 django 中编写了一些原始查询,我注意到相同的查询会根据给它的值而崩溃。在这两种情况下,都会创建 rawqueryset,当我尝试评估它时会发生崩溃。

具体来说:这个查询集会崩溃

<RawQuerySet: 'select * from (select * from flingfix_user_profile where domain=illinois and sex=F)
as a left outer join (select * from flingfix_rating where rater_id=24) as b ON
a.id = b.ratee_id where rater_id IS NULL and a.id not in [0] LIMIT 10'>

但是这个查询集不会

<RawQuerySet: 'select * from (select * from flingfix_user_profile where domain=illinois and sex=F)
as a left outer join (select * from flingfix_rating where rater_id=24) as b ON
a.id = b.ratee_id where rater_id IS NULL and a.id not in [0,1] LIMIT 10'>

(区别是查询末尾附近的 [0] vs [0,1])

我正在使用以下代码构建查询:

query = 'select * from (select * from flingfix_user_profile where
domain=%s and sex=%s) as a left outer join (select * from flingfix_rating where
rater_id=%s) as b ON a.id = b.ratee_id where rater_id IS NULL and a.id 
not in %s LIMIT %s'

params = ['illinois', 'F', '24', [0], 10]

qs = MyModel.objects.raw(query,params)

在我尝试评估查询集之前不会发生错误。例如qs = list(qs)

这是错误:

 Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 1548, in     __iter__
query = iter(self.query)
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 72, in __iter__
self._execute_query()
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 86, in _execute_query
self.cursor.execute(self.sql, self.params)
  File "/usr/lib/python2.6/site-packages/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
  File "/usr/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 130, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
  File "/usr/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 120, in execute
return self.cursor.execute(query, args)
  File "/usr/lib/python2.6/site-packages/MySQLdb/cursors.py", line 173, in execute
self.errorhandler(self, exc, value)
  File "/usr/lib/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to yo
ur MySQL server version for the right syntax to use near ') LIMIT 10' at line 1")

我的意思是,我可以轻松地确保列表至少有 2 个元素长,但我不希望这样做。另外,我很好奇为什么会发生这种情况。

4

2 回答 2

3

SQLin子句通常需要在括号之间列出 0 个或多个值,而不是方括号。您正在生成无效的 SQL。

您需要生成适当数量的 SQL 参数,而不是在此处传入列表:

query = 'select * from (select * from flingfix_user_profile where
domain=%s and sex=%s) as a left outer join (select * from flingfix_rating where
rater_id=%s) as b ON a.id = b.ratee_id where rater_id IS NULL and a.id 
not in ({}) LIMIT %s'.format(','.join(['%s' for _ in range(len(parameters))]))

parameters您要测试的值列表在哪里not in,并将这些参数作为params列表的元素传递:

params = ['illinois', 'F', '24'] + parameters + [10]
qs = MyModel.objects.raw(query,params)

上面的查询调整现在生成not in (%s, %s)两个值,not in (%s)只有一个,从那时起,MySQL 将正确处理参数。

于 2013-11-03T08:53:11.767 回答
0

在 where 子句中:

and a.id not in [0,1] LIMIT 10 OR
a.id not in [0] LIMIT 10

你应该这样写:

and a.id not in (0,1) LIMIT 10 OR
a.id not in (0) LIMIT 10
于 2013-11-03T08:50:40.117 回答