Миграции Django - как применить новые правила к ранее сохраненным экземплярам модели?

Допустим, у меня есть следующая модель, и у меня уже есть несколько экземпляров модели, сохраненных в базе данных -

class Comment(models.Model):
    comment_text = models.CharField(max_length=255)

Теперь, если я хочу изменить аргумент max_length на 127 вместо 255 и применить миграции, старые экземпляры все еще будут в базе данных, где некоторые могут иметь длину более 127, что не подчиняется новым миграциям.

Какой наилучший подход к миграции всех предыдущих данных вместе с новыми правилами миграции?

Вы должны написать свою миграцию и применить ее до сгенерированной миграции (которая изменяет модель).

Для этого сначала нужно написать миграцию. Поместите ее в папку migrations приложения. Затем добавьте ее имя в поле dependencies сгенерированной миграции.

Этот пример обновляет поле uuid всех MyModel объектов. И находится в my_migration.py

# Generated by Django A.B on YYYY-MM-DD HH:MM
from django.db import migrations
import uuid

def gen_uuid(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    for row in MyModel.objects.all():
        row.uuid = uuid.uuid4()
        row.save(update_fields=['uuid'])

class MyMigration(migrations.Migration):

    dependencies = [
        ('myapp', '0004_add_uuid_field'),
    ]

    operations = [
        # omit reverse_code=... if you don't want the migration to be reversible.
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
    ]

Предположим, что сгенерированная вами миграция, изменяющая MyModel, называется GeneratedMigration.. отредактируйте сгенерированный файл миграций следующим образом.

class GeneratedMigration(migrations.Migration):

    dependencies = [
        ('myapp', 'my_migration'),
    ]

Вы также можете использовать атрибут run_before.

Просмотрите документацию djano по написанию миграций для получения дополнительной информации.

Вернуться на верх