2016-09-22 2 views
3

У меня есть производственная база данных и вам необходимо сохранить данные. Я хочу изменить поле в модели и преобразовать все данные внутри этой базы данных с этим изменением.Преобразование данных на миграцию django AlterField

Старый поле

class MyModel(models.Model): 
    field_name = models.TimeField() 

Измененное поле

class MyModel(models.Model): 
    field_name = models.PositiveIntegerField() 

В основном я хочу, чтобы преобразовать значение TIMEFIELD (то есть объект Time) в течение нескольких минут.

Пример: У меня есть объект time(hour=2, minute=0, second=0), и я хочу преобразовать это значение поля во всю таблицу базы данных в 120 при применении переноса.

ответ

3

Safest так, что я всегда делаю это:

  1. создать еще одно поле с field_name_new = models.PositiveIntegerField()
  2. мигрируют это новое поле на производственной БД
  3. сделать миграцию данных (преобразование field_name значение и переместить преобразованное значение поле field_name_new)
  4. изменить код, чтобы использовать field_name_new
  5. развернуть шаг 4
  6. удалить поле field_name
  7. перенастроить шаг 6 на производственной БД и развернуть его (шаг 6)

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

6

В прошлом я всегда делал это с помощью операции Djangos RunPython. Создайте настраиваемую миграцию, которая обрабатывает следующее.

  1. Изменить название поля.
  2. Добавить новое поле желаемого типа.
  3. RunPython для обработки логики преобразования от одного к другому.
  4. Удалить старые поля.


def migrate_time_to_positive_int(apps, schema_editor): 

    MyModel = apps.get_model('myapp', 'MyModel') 

    for mm in MyModel.objects.all(): 

     field_old_time = mm.field_name_old 
     field_new_int = field_old_time.total_seconds()/60 
     mm.field_name = field_new_int 
     mm.save() 

class Migration(migrations.Migration): 

    operations = [ 
     migrations.RenameField(
      model_name='mymodel', 
      old_name='field_name', 
      new_name='field_name_old', 
     ), 
     migrations.AddField(
      model_name='mymodel', 
      name='field_name', 
      field=models.PositiveIntegerField(), 
     ), 
     migrations.RunPython(migrate_time_to_positive_int), 
     migrations.RemoveField(
      model_name='mymodel', 
      name='field_name_old', 
     ) 
    ] 

field_name_old.total_seconds()/60, возможно, потребуется скорректировать, но вы получите идею.

+0

Это очень интересно, я тоже попробую. благодаря –

Смежные вопросы