# Generated by Django on 2025-05-23 12:00
|
|
from django.db import migrations, connections
|
from django.conf import settings
|
from core.redis import start_job_async_or_sync
|
from core.models import AsyncMigrationStatus
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
migration_name = '0054_add_brin_index_updated_at'
|
|
def forward_migration(migration_name, db_alias):
|
migration = AsyncMigrationStatus.objects.using(db_alias).create(
|
name=migration_name,
|
status=AsyncMigrationStatus.STATUS_STARTED,
|
)
|
logger.debug(f'Start async migration {migration_name}')
|
|
# Check database backend and use appropriate SQL
|
conn = connections[db_alias]
|
if conn.vendor == 'postgresql':
|
# Create BRIN index concurrently to avoid blocking writes
|
sql = '''
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS "task_updated_at_brin_idx"
|
ON "task" USING BRIN ("updated_at");
|
'''
|
else:
|
# SQLite fallback - regular B-tree index
|
sql = '''
|
CREATE INDEX IF NOT EXISTS "task_updated_at_brin_idx"
|
ON "task" ("updated_at");
|
'''
|
|
with conn.cursor() as cursor:
|
cursor.execute(sql)
|
|
migration.status = AsyncMigrationStatus.STATUS_FINISHED
|
migration.save(using=db_alias)
|
logger.debug(f'Async migration {migration_name} complete')
|
|
def reverse_migration(migration_name, db_alias):
|
migration = AsyncMigrationStatus.objects.using(db_alias).create(
|
name=migration_name,
|
status=AsyncMigrationStatus.STATUS_STARTED,
|
)
|
logger.debug(f'Start async migration rollback {migration_name}')
|
|
# Drop index (works for both PostgreSQL and SQLite)
|
conn = connections[db_alias]
|
if conn.vendor == 'postgresql':
|
sql = 'DROP INDEX CONCURRENTLY IF EXISTS "task_updated_at_brin_idx";'
|
else:
|
sql = 'DROP INDEX IF EXISTS "task_updated_at_brin_idx";'
|
|
with conn.cursor() as cursor:
|
cursor.execute(sql)
|
|
migration.status = AsyncMigrationStatus.STATUS_FINISHED
|
migration.save(using=db_alias)
|
logger.debug(f'Async migration rollback {migration_name} complete')
|
|
def forwards(apps, schema_editor):
|
db_alias = schema_editor.connection.alias
|
start_job_async_or_sync(forward_migration, migration_name=migration_name, db_alias=db_alias)
|
|
def backwards(apps, schema_editor):
|
db_alias = schema_editor.connection.alias
|
start_job_async_or_sync(reverse_migration, migration_name=migration_name, db_alias=db_alias)
|
|
|
class Migration(migrations.Migration):
|
atomic = False
|
|
dependencies = [
|
("tasks", "0053_annotation_bulk_created"),
|
]
|
|
operations = [
|
migrations.RunPython(forwards, backwards),
|
]
|