Как правильно перенести значения Enumfield в Django? - PullRequest
0 голосов
/ 04 марта 2020

Предположим, у нас есть Enum:

class MyEnum(Enum):
    FOO = "FOO"  
    BAR = "BAR"  
    BAZ = "BAZ"

, который используется в поле:

from enumfields import EnumField

    class FooModel (models.Model)   
        foo_field = EnumField(
            MyEnum, null=True, blank=True, default=MyEnum.FOO)

Затем я хочу удалить одно из полей в MyEnum, потому что я мне больше не нужно значение FOO в моей базе данных

class MyEnum(Enum):
    BAR = "BAR"  
    BAZ = "BAZ"
from enumfields import EnumField

    class FooModel (models.Model)   
        foo_field = EnumField(
            MyEnum, null=True, blank=True, default=MyEnum.BAR)

Мне нужно перенести данные, поэтому моя миграция может выглядеть так:

def migrate_not_for_sale_to_private(apps, schema_editor):
    FooModel = apps.get_model("foo", "FooModel")
    for obj in FooModel.objects.all():
        if obj.foo_field == "FOO":
            obj.foo_field = "BAR"
            obj.save()

Эта ошибка не выполняется, потому что я изменил разрешающие значения для foo_field на BAR и BAZ, и поэтому, если obj имеет значение FOO, он взорвется с ошибкой недопустимого значения.

Как это сделать должным образом? Я мог бы оставить значения MyEnum такими, какие они есть, пометив одно из них как устаревшее, но в конечном итоге это приведет к появлению множества потенциальных устаревших полей. Другой способ - запустить команду raw SQL (предположим, я использую PostgreSQL).

1 Ответ

0 голосов
/ 04 марта 2020
  1. Изменить default=MyEnum.FOO на default=MyEnum.BAR
  2. Заблокировать любые новые FOO записи из кода
  3. Переносить все FOO объекты в BAR из БД
  4. Удалите FOO enum

Около 2. Вы можете перезаписать функцию def save(self, *args, **kwargs): для своих FooModel, чтобы изменить любые новые FOO объекты на BAR (или поднять ошибку)

...