Можно ли перейти на сквозную модель в одном релизе?

Предположим, что у меня есть эти модели Django:

class Book(models.Model):
    title = models.CharField(max_length=100)

class Author(models.Model):
    name = models.CharField(max_length=100)
    books = models.ManyToManyField(Book)

У меня уже есть производственная система с несколькими объектами и несколькими соединениями Author <-> Book.

Теперь я хочу переключиться на:

class Book(models.Model):
    title = models.CharField(max_length=100)

class BookAuthor(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    author = models.ForeignKey("Author", on_delete=models.CASCADE)
    impact = models.IntegerField(default=1)

    class Meta:
        unique_together = ("book", "author")

class Author(models.Model):
    name = models.CharField(max_length=100)
    books = models.ManyToManyField(Book, through=BookAuthor)

Если я сделаю эту миграцию:

from django.db import migrations

def migrate_author_books(apps, schema_editor):
    Author = apps.get_model('yourappname', 'Author')
    BookAuthor = apps.get_model('yourappname', 'BookAuthor')

    for author in Author.objects.all():
        for book in author.books.all():
            # Create a BookAuthor entry with default impact=1
            BookAuthor.objects.create(author=author, book=book, impact=1)

class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', 'previous_migration_file'),
    ]

    operations = [
        migrations.RunPython(migrate_author_books),
    ]

тогда цикл for book in author.books.all() будет обращаться к новой (и пустой) BookAuthor таблице вместо итерации по существующей таблице, созданной Django по умолчанию.

Как осуществить миграцию данных?

Единственный способ, который я вижу, - это два выпуска:

  1. Просто добавьте новую BookAuthor модель и заполните ее данными, но сохраните существующую. То есть вводим новое поле и сохраняем старое. Также измените все места, где используется author.books на author.books_new
  2. .
  3. Release + migrate on prod
  4. Удалите author.books и переименуйте books_new в books. Еще одна миграция, еще один релиз.

Разве нет более простого способа?

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