Можно ли перейти на сквозную модель в одном релизе?
Предположим, что у меня есть эти модели 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 по умолчанию.
Как осуществить миграцию данных?
Единственный способ, который я вижу, - это два выпуска:
- Просто добавьте новую
BookAuthor
модель и заполните ее данными, но сохраните существующую. То есть вводим новое поле и сохраняем старое. Также измените все места, где используется author.books наauthor.books_new
.
- Release + migrate on prod
- Удалите author.books и переименуйте books_new в books. Еще одна миграция, еще один релиз.
Разве нет более простого способа?