Django4.0 遷移-數(shù)據(jù)遷移

2022-03-16 17:50 更新

除了改變數(shù)據(jù)庫架構(gòu)外,你還可以使用遷移來改變數(shù)據(jù)庫本身的數(shù)據(jù),如果你想的話,還可以結(jié)合架構(gòu)來改變。

更改數(shù)據(jù)的遷移通常稱為“數(shù)據(jù)遷移”;最好將它們寫成單獨的遷移,與架構(gòu)遷移放在一起。

Django 無法像架構(gòu)遷移那樣自動為您生成數(shù)據(jù)遷移,但是編寫它們并不難。Django 中的遷移文件是由 ?Operations ?組成的,你用于數(shù)據(jù)遷移的主要操作是 ?RunPython?。

首先,制作一個可以使用的空遷移文件(Django 會將文件放在正確的位置,提供一個名稱,并為你添加依賴項):

python manage.py makemigrations --empty yourappname

然后,打開文件;它應(yīng)該是這樣的:

# Generated by Django A.B on YYYY-MM-DD HH:MM
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', '0001_initial'),
    ]

    operations = [
    ]

現(xiàn)在,你需要做的就是創(chuàng)建一個新的函數(shù),讓 ?RunPython ?使用它。?RunPython ?需要一個可調(diào)用對象作為它的參數(shù),這個可調(diào)用對象需要兩個參數(shù)——第一個是 應(yīng)用注冊表 ,其中加載了所有模型的歷史版本,以匹配遷移所在的位置,第二個是 ?SchemaEditor?,你可以用它來手動實現(xiàn)數(shù)據(jù)庫架構(gòu)的變更(但要注意,這樣做會混淆遷移自動檢測器!)
讓我們編寫一個遷移,使用 first_name 和 last_name 的組合值填充新的 name 字段(我們已經(jīng)意識到,并不是每個人都有名字和姓氏)。 我們需要做的就是使用歷史模型并對行進行迭代:

from django.db import migrations

def combine_names(apps, schema_editor):
    # We can't import the Person model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    Person = apps.get_model('yourappname', 'Person')
    for person in Person.objects.all():
        person.name = '%s %s' % (person.first_name, person.last_name)
        person.save()

class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(combine_names),
    ]

完成后,我們可以像往常一樣運行 ?python manage.py migrate?,數(shù)據(jù)遷移將與其他遷移一起運行。
您可以將第二個可調(diào)用對象傳遞給 ?RunPython ?以運行撤銷遷移時要執(zhí)行的任何邏輯。 如果忽略此可調(diào)用對象,則撤銷遷移將引發(fā)異常。

從其他應(yīng)用訪問模型

在編寫使用來自遷移所在應(yīng)用以外的其他應(yīng)用模型的 ?RunPython ?函數(shù)時,遷移的 ?dependencies ?屬性應(yīng)包括所涉及的每個應(yīng)用程序的最新遷移,否則當(dāng)你嘗試使用 ?apps.get_model()? 在 ?RunPython ?函數(shù)中獲取模型時,你可能會得到? LookupError: No installed app with label 'myappname'?。
在下面的例子中,我們在 app1 中進行遷移,需要使用 app2 中的模型。我們不關(guān)心 move_m1 的細節(jié),只關(guān)心它需要訪問兩個應(yīng)用程序的模型。因此,我們添加了一個依賴關(guān)系,指定 app2 最后一次遷移:

class Migration(migrations.Migration):

    dependencies = [
        ('app1', '0001_initial'),
        # added dependency to enable using models from app2 in move_m1
        ('app2', '0004_foobar'),
    ]

    operations = [
        migrations.RunPython(move_m1),
    ]


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號