Django: использование sqlsequencereset программно внутри пользовательской команды
Я пытаюсь создать пользовательскую команду на Django, которая будет использовать команду sqlsequencereset
для списка ярлыков приложений внутри цикла, идея заключается в том, чтобы запустить эту команду для создания и выполнения последовательности setval
запросов для каждой таблицы приложения.
Моя реализация:
for app_label in app_labels:
output = call_command("sqlsequencereset", app_label)
with connection.cursor() as cursor:
cursor.execute(output)
Я прочитал в документации Django, что необработанные запросы внутри cursor.execute
не поддерживают транзакции, поэтому я настроил строку SQL так, чтобы она не включала ключевые слова BEGIN
и COMMIT
, но она все равно выдает следующую синтаксическую ошибку:
File "/home/python/.local/lib/python3.12/site-packages/django/db/backends/utils.py", line 122, in execute
return super().execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.12/site-packages/django/db/backends/utils.py", line 79, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.12/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/python/.local/lib/python3.12/site-packages/django/db/backends/utils.py", line 100, in _execute
with self.db.wrap_database_errors:
File "/home/python/.local/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/python/.local/lib/python3.12/site-packages/django/db/backends/utils.py", line 103, in _execute
return self.cursor.execute(sql)
^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.ProgrammingError: syntax error at or near "
LINE 1: BEGIN;
Функция call_command(…)
[Django-doc] возвращает не то, что печатает команда. Команда просто выводит данные в stdout.
Вы можете перехватить вывод, сохранив stdout в StringIO
Мы можем перехватить результат и использовать его в запросе:
from io import StringIO
output = StringIO()
for app_label in app_labels:
output = call_command('sqlsequencereset', app_label, stdout=output)
with connection.cursor() as cursor:
cursor.execute(output.getvalue())
По-видимому, стилизация выводимого текста была цветной, из-за чего курсор не мог обработать его в консоли запросов. Я смог заставить его работать, используя аргумент no_color с командой sqlsequencereset
:
for app_label in app_labels:
output = call_command("sqlsequencereset", app_label, no_color=True, database='default')
with connection.cursor() as cursor:
cursor.execute(output)