1

質問: django の "in" 句では、リストに 2 つの値が必要ですか?

私は 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] 対 [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

通常、 SQL句には、角括弧ではなく、括弧inで囲まれた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))]))

whereparametersは、テストする値のリストであり、それらのパラメーターをリストnot inの要素として渡します。params

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

上記のクエリ調整は、1 つのみnot in (%s, %s)に対して 2 つの値を生成する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 に答える