Что такое Database migration failed?
Ошибка Database migration failed
возникает, когда автоматическое применение миграций базы данных в CI/CD пайплайне завершается неудачно из-за различных проблем с схемой или данными.
Причины возникновения
- Конфликты схемы базы данных
- Проблемы с подключением к БД
- Недостаточно прав доступа
- Проблемы с данными в таблицах
- Ошибки в SQL скриптах миграций
- Проблемы с транзакциями
- Несовместимость версий БД
Как отладить ошибку
- Проверь логи миграций - найди точную ошибку
- Проверь подключение к БД - убедись в доступности
- Проверь права доступа - убедись в наличии прав
- Проверь схему БД - убедись в совместимости
- Проверь данные - убедись в целостности
Как исправить ошибку
1. Настрой правильное подключение к БД
1# Django settings для миграций
2DATABASES = {
3 'default': {
4 'ENGINE': 'django.db.backends.postgresql',
5 'NAME': os.environ.get('DB_NAME'),
6 'USER': os.environ.get('DB_USER'),
7 'PASSWORD': os.environ.get('DB_PASSWORD'),
8 'HOST': os.environ.get('DB_HOST'),
9 'PORT': os.environ.get('DB_PORT', '5432'),
10 'OPTIONS': {
11 'sslmode': 'require',
12 },
13 }
14}
2. Настрой CI/CD для миграций
1# .github/workflows/migrations.yml
2name: Database Migrations
3on: [push]
4
5jobs:
6 migrate:
7 runs-on: ubuntu-latest
8 steps:
9 - uses: actions/checkout@v3
10
11 - name: Set up Python
12 uses: actions/setup-python@v4
13 with:
14 python-version: '3.11'
15
16 - name: Install dependencies
17 run: pip install -r requirements.txt
18
19 - name: Wait for database
20 run: |
21 until pg_isready -h ${{ secrets.DB_HOST }} -p ${{ secrets.DB_PORT }}; do
22 echo "Waiting for database..."
23 sleep 2
24 done
25
26 - name: Run migrations
27 run: |
28 python manage.py migrate --noinput
29 env:
30 DATABASE_URL: ${{ secrets.DATABASE_URL }}
3. Настрой проверку миграций
4. Настрой откат миграций
1# Скрипт для отката миграций
2#!/usr/bin/env python
3import os
4import django
5
6os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
7django.setup()
8
9from django.db import connection
10
11def rollback_migration(app_name, migration_name):
12 with connection.cursor() as cursor:
13 # Откат конкретной миграции
14 cursor.execute(f"""
15 DELETE FROM django_migrations
16 WHERE app = '{app_name}' AND name = '{migration_name}'
17 """)
18 print(f"Rolled back {app_name}.{migration_name}")
19
20# Использование
21rollback_migration('myapp', '0002_add_field')
5. Настрой резервное копирование перед миграциями
1#!/bin/bash
2# backup-before-migration.sh
3
4DB_NAME="$1"
5BACKUP_DIR="/backups"
6
7echo "Creating backup before migration..."
8
9# Создание резервной копии
10pg_dump "$DB_NAME" > "$BACKUP_DIR/backup_$(date +%Y%m%d_%H%M%S).sql"
11
12echo "Backup created successfully"
13
14# Применение миграций
15python manage.py migrate
16
17if [ $? -ne 0 ]; then
18 echo "Migration failed, restoring backup..."
19 psql "$DB_NAME" < "$BACKUP_DIR/backup_$(date +%Y%m%d_%H%M%S).sql"
20 exit 1
21fi
Как мониторить подобные ошибки
- Настрой алерты на failed migrations
- Мониторь время выполнения миграций
- Отслеживай успешность миграций
- Настрой мониторинг состояния БД
- Используй метрики для анализа проблем
FAQ
В: Как избежать проблем с миграциями в production?
О: Тестируй миграции на staging, используй резервные копии, применяй zero-downtime миграции.
В: Что делать с большими миграциями?
О: Разбивай на маленькие миграции, используй background jobs, применяй миграции в off-peak время.
В: Как отладить проблемы с данными в миграциях?
О: Используй data migrations, тестируй на копиях данных, применяй валидацию данных.
Лучшие практики
- Всегда тестируй миграции на staging
- Создавай резервные копии перед миграциями
- Используй транзакции для атомарности
- Документируй сложные миграции
- Настрой мониторинг состояния БД
- Используй zero-downtime миграции