Джанго - Можно ли разделить один класс модели на два класса модели, сохранив данные до разделения? - PullRequest
1 голос
/ 30 сентября 2019

В Django можно разделить один класс модели на два класса модели, сохранив ранее введенные данные?

Исходная модель:

class Fruit(models.Model):
    name = models.CharField(max_length=100)
    color = models.CharField(max_length=100)
    taste_description = models.CharField(max_length=100)
    tasty = models.BooleanField()

Модели разделения:

class Fruit(models.Model):
    name = models.CharField(max_length=100)
    color = models.CharField(max_length=100)

class Fruittaste(models.Model):
    fruit = models.ForeignKey(Fruit, on_delete=models.CASCADE)
    taste_description = models.CharField(max_length=100)
    tasty = models.BooleanField()

Ответы [ 3 ]

1 голос
/ 30 сентября 2019

1 / создайте новую модель, оставив исходную без изменений

2 / сделайте миграцию, чтобы создать модель, запустите ее, добавьте в свой контроль версий

3 / создайте пустуюмиграции для вашего приложения, и в этой миграции напишите код миграции данных

def forward(apps, schema_editor):
    # VERY important: don't import the models, 
    # get them from `app.get_model()`
    Fruit = apps.models.get("yourappname", "Fruit")
    Fruittaste = apps.models.get("yourappname", "Fruittast")

    data = [        Fruittaste(fruit=fruit,taste_description=fruit.tase_description,tasty=fruit.tasty) for fruit in Fruit.objects.all()
    ]
    Fruittaste.objects.bulk_create(data)


class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', '000x_previous_migration'),
    ]

    operations = [
        migrations.RunPython(forward),
    ]

Примечание: в зависимости от размера набора данных вы также можете записывать новые записи в БД по одной вместособирать их в список и отправить целое в bulk_create. Это будет медленнее, но потребляет меньше памяти.

NB. По возможности следует добавлять обратную миграцию, но в приведенном выше случае вам придется произвольно выбирать один из множества возможных вкусов для каждого фрукта. итак ...

4 / и, наконец, удалите устаревшие поля из Fruit, сделайте и запустите миграцию и т. д. (не забывайте добавлять файлы миграции в вашу версию cotrol !!!).

1 голос
/ 30 сентября 2019

Нет простого или единственного командного способа сделать это. Это можно сделать следующим образом:

  1. Создать новую модель, но сохранить оригинальную модель без изменений, т.е. не удалять поля

  2. Запуститьскрипт для передачи всех данных в новую модель

  3. Запустите тесты, чтобы проверить, правильно ли работают ваш код и представления

  4. Удалите ненужные и старые поляв основной модели на досуге

Надеюсь, это поможет!

0 голосов
/ 30 сентября 2019
  • Шаг 1: создать Fruittaste модель и запустить миграцию (без изменения Fruit)

  • Шаг 2: выполнить следующий запрос для заполнения Fruittase.

    data = []
    
    from .models import Fruit, Fruittaste
    
    for fruit in Fruit.objects.all():
        data.append(
        Fruittaste(
            fruit = fruit,
            taste_description = fruit.tase_description,
            tasty = fruit.tasty
        ))
    
    Fruittaste.objects.bulk_create(data)
    

Теперь вы можете удалить повторяющиеся строки из Fruit и снова выполнить миграцию.

...