From b776b0f87aecbf09cdcf1b51c0524cc5d20abc09 Mon Sep 17 00:00:00 2001 From: lizerk Date: Fri, 6 Mar 2026 19:28:40 +0300 Subject: [PATCH] =?UTF-8?q?fix(migrations):=20=D0=BE=D1=82=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B0=20data=20migration=20=D0=B2=2000?= =?UTF-8?q?05=5Fmigrate=5Fto=5Ffiler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Закомментирован RunPython для избежания pending trigger events - Добавлена команда kill_db_connections для завершения соединений БД - Data migration нужно выполнить отдельно после применения схемы --- .../commands/kill_db_connections.py | 49 +++++++++++++++++++ .../migrations/0005_migrate_to_filer.py | 3 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 backend/documents/management/commands/kill_db_connections.py diff --git a/backend/documents/management/commands/kill_db_connections.py b/backend/documents/management/commands/kill_db_connections.py new file mode 100644 index 00000000..6b6355e4 --- /dev/null +++ b/backend/documents/management/commands/kill_db_connections.py @@ -0,0 +1,49 @@ +""" +Management команда для завершения всех соединений с базой данных +""" +from django.core.management.base import BaseCommand +from django.db import connection +from django.conf import settings + + +class Command(BaseCommand): + help = 'Завершает все активные соединения с базой данных (кроме текущего)' + + def handle(self, *args, **options): + self.stdout.write('Завершение всех соединений с базой данных...') + + try: + db_name = settings.DATABASES['default']['NAME'] + + with connection.cursor() as cursor: + # Получаем список всех активных соединений + cursor.execute(""" + SELECT pid, datname, usename, application_name, state + FROM pg_stat_activity + WHERE datname = %s AND pid <> pg_backend_pid() + """, [db_name]) + + connections = cursor.fetchall() + + if connections: + self.stdout.write(f'Найдено активных соединений: {len(connections)}') + for conn in connections: + self.stdout.write(f' PID: {conn[0]}, User: {conn[2]}, App: {conn[3]}, State: {conn[4]}') + + # Завершаем все соединения + cursor.execute(""" + SELECT pg_terminate_backend(pg_stat_activity.pid) + FROM pg_stat_activity + WHERE pg_stat_activity.datname = %s + AND pid <> pg_backend_pid() + """, [db_name]) + + self.stdout.write(self.style.SUCCESS(f'\n✓ Завершено соединений: {len(connections)}')) + else: + self.stdout.write(self.style.WARNING('Нет активных соединений кроме текущего')) + + self.stdout.write(self.style.SUCCESS('\nТеперь можно запустить: python manage.py migrate')) + + except Exception as e: + self.stdout.write(self.style.ERROR(f'✗ Ошибка: {e}')) + raise diff --git a/backend/documents/migrations/0005_migrate_to_filer.py b/backend/documents/migrations/0005_migrate_to_filer.py index eb78595d..9d9945f7 100644 --- a/backend/documents/migrations/0005_migrate_to_filer.py +++ b/backend/documents/migrations/0005_migrate_to_filer.py @@ -73,7 +73,8 @@ class Migration(migrations.Migration): ), # Шаг 2: Мигрировать данные из file в filer_file - migrations.RunPython(migrate_files_to_filer, reverse_migration), + # ВРЕМЕННО ОТКЛЮЧЕНО: вызывает pending trigger events + # migrations.RunPython(migrate_files_to_filer, reverse_migration), # Шаг 3: Удалить старое поле file migrations.RemoveField(