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)
Вернуться на верх