A .raw(..)
- это , а не выполняется с нетерпением, как и большинство запросов Django ORM, выполняемых лениво.Таким образом, он возвращает RawQuerySet
объект с запросом в объекте.Например:
>>> User.objects.raw('BLA BLA BLA', [])
<RawQuerySet: BLA BLA BLA>
Запрос, подобный BLA BLA BLA
, не имеет никакого смысла: в нем возникнет ошибка базы данных, но мы все равно получим RawQuerySet
.
Вы можете принудительно выполнить оценкунапример, перебрав его, мы получим:
>>> list(User.objects.raw('BLA BLA BLA', []))
Traceback (most recent call last):
File "/djangotest/env/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/djangotest/env/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 71, in execute
return self.cursor.execute(query, args)
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
self.errorhandler(self, exc, value)
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
raise errorvalue
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
res = self._query(query)
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/cursors.py", line 412, in _query
rowcount = self._do_query(q)
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/cursors.py", line 375, in _do_query
db.query(q)
File "/djangotest/env/lib/python3.6/site-packages/MySQLdb/connections.py", line 276, in query
_mysql.connection.query(self, query)
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BLA BLA BLA' at line 1")
Таким образом, list(..)
форсирует оценку, и теперь база данных, конечно, выдает ошибку.Однако даже если бы это был действительный запрос DELETE
, он все равно вызвал бы ошибку, поскольку такой запрос не возвращает никакой записи.
Для выполнения вызовов DELETE
В руководстве по Django указано, что вы должны использовать курсор [Django-doc] :
from django.db import connection
with connection.cursor() as cursor:
cursor.execute(
"DELETE FROM mydb_mymodel WHERE s_type = '%s' AND barcode = '%s' AND shopcode = '%s' AND date = '%s'" ,
[d.s_type,d.barcode,d.shopcode,d.date]
)
Но я думаю, что, вероятно, намного проще указать его следующим образом:
MyModel.objects.filter(
s_type=d.s_type,
barcode=d.barcode,
shopcode=d.shopcode,
date=d.date
).delete()
Это создаст запрос DELETE
и правильно сериализует параметры.Запрос .delete()
выполняется с нетерпением, поэтому вероятность совершения вышеописанных ошибок намного ниже: если ORM реализован правильно, нам не нужно об этом беспокоиться.