Django ORM необработанный запрос на удаление, не удаляющий записи

Несколько увеличивая ваши требования и предполагая, что вас не интересует порядок строк и вы хотите их сгруппировать по категориям, для вас может работать следующее решение:

>>> fname = "lines.txt"
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> with open(fname) as f:
...     for line in f:
...         text, cat = line.rstrip("\n").split(",", 1)
...         dct[cat].append(text)
...
>>> dct
defaultdict(<type 'list'>, {' CatA': ['This is the first line', 'This is the another line'], ' CatC': ['This is the third line'], ' CatB': ['This is the second line', 'This is the last line']})

Таким образом, вы получаете все соответствующие строки доступны в словаре под ключом, являющимся категорией.

2
задан Yugandhar Chaudhari 2 March 2019 в 13:29
поделиться

1 ответ

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 реализован правильно, нам не нужно об этом беспокоиться.

0
ответ дан Willem Van Onsem 2 March 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: