2016-09-22 112 views
3

我有一個生產數據庫,需要保證數據的安全。我想要更改模型中的Field,並使用此更改轉換該數據庫內的所有數據。在AlterField django遷移上轉換數據

老場

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

,我總是做最安全的方法是:

  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

這很有趣,我也會試試。謝謝 –