https://www.aliyun.com/jiaocheng/485568.html
摘要:https://docs.djangoproject.com/en/dev/topics/migrations/遷移Django1.7i新特性Migrations是Django的方式將模型變更(添加一個(gè)字段,刪除模型等)映射到數(shù)據(jù)庫schema钥弯。它們設(shè)計(jì)成大部分都是自動進(jìn)行的,但你需要知道什么時(shí)候做遷移,和運(yùn)行遷移時(shí)你可能遇到的常見問題竟块。一個(gè)簡短的歷史1.7版本之前,Django只支持新增模型到數(shù)據(jù)庫中;通過syncdb(migrate的前身)命令變更或者刪除現(xiàn)存的模型市不可
https://docs.djangoproject.com/en/dev/topics/migrations/
遷移?Django 1.7i 新特性
Migrations是Django的方式將模型變更(添加一個(gè)字段,刪除模型等)映射到數(shù)據(jù)庫schema少辣。它們設(shè)計(jì)成大部分都是自動進(jìn)行的,但你需要知道什么時(shí)候做遷移,和運(yùn)行遷移時(shí)你可能遇到的常見問題。
一個(gè)簡短的歷史
1.7版本之前,Django只支持新增模型到數(shù)據(jù)庫中;通過syncdb(migrate的前身)命令變更或者刪除現(xiàn)存的模型市不可能的笤成。
第三方工具,尤其是South,支持這些增加的變更類型,但是現(xiàn)在被認(rèn)為已經(jīng)足夠重要到需要引入到django的core中去评架。
2條命令
你將使用2條命令進(jìn)行遷移和操縱數(shù)據(jù)庫schema:
migrate,用來使遷移生效,以及未生效時(shí)報(bào)告它們的狀態(tài)。
makemigrations,用來根據(jù)你對模型做的變更創(chuàng)建新的遷移腳本炕泳。
值得注意的是,遷移是創(chuàng)建和運(yùn)行在每個(gè)應(yīng)用程序的基礎(chǔ)上纵诞。特別是,對部分應(yīng)用程序不使用遷移是可能的(稱為“不遷移”的應(yīng)用),這些應(yīng)用程序?qū)⑷〈M只是添加新的模型傳統(tǒng)的行為。
你應(yīng)該把遷移作為你的數(shù)據(jù)庫架構(gòu)的版本控制系統(tǒng)培遵。makemigrations負(fù)責(zé)包裝你的模型變更到獨(dú)立的遷移文件中-類似于提交代碼-migrate負(fù)責(zé)應(yīng)用到你的數(shù)據(jù)庫中浙芙。
遷移文件存放在每個(gè)應(yīng)用程序的一個(gè)“migrations”目錄中,被設(shè)計(jì)成提交,和作為發(fā)布的一部分,到代碼庫中。你應(yīng)該在你的開發(fā)機(jī)器上使用它們,然后在你的同事的機(jī)器上運(yùn)行相同的遷移腳本,staging machines,最終在你的生產(chǎn)機(jī)器籽腕。
注意
在逐個(gè)app基礎(chǔ)上,覆蓋存放遷移腳本的包的名字是可以的,只要修改MIGRATION_MODULES設(shè)置嗡呼。
遷徙將在相同的數(shù)據(jù)集上以相同的方法運(yùn)行并產(chǎn)生一致的結(jié)果,這意味著你將看到在開發(fā)階段,staging階段,在相同的情況下,和生產(chǎn)環(huán)境上的表現(xiàn)完全一致。
Django會遷移你對模型或字段所做的任何變更 - 甚至是不影響數(shù)據(jù)庫的選項(xiàng) - 因?yàn)槲ㄒ荒苷_的重建一個(gè)字段的方式是記錄它發(fā)生所有的變更,而你可能需要這些選項(xiàng)應(yīng)用在以后的一些數(shù)據(jù)遷移中(例如,如果你設(shè)置了自定義驗(yàn)證器)皇耗。
后端支持
遷移支持django使用的所有后端,以及所有支持schema變更(通過SchemaEditor類完成)的第三方后端南窗。
然后,一些數(shù)據(jù)庫有更好的schema遷移支持能力;在下面描述了一些注意事項(xiàng)。
PostgreSQL
PostgreSQL在所有數(shù)據(jù)庫中有最好的schema支持能力;唯一的注意事項(xiàng)是添加一個(gè)有默認(rèn)值的列時(shí)會導(dǎo)致表全部重寫,所需時(shí)間和表的規(guī)模成比例郎楼。
因?yàn)檫@個(gè)原因,推薦你創(chuàng)建新列時(shí)總是設(shè)置成null=True,這樣能立即添加万伤。
MySQL
MySQ對于schema變更操作缺乏事務(wù)支持,意味著如果遷移失敗,你必須手動回退變更然后才能重新遷移。 (回滾到之前的某個(gè)點(diǎn)是可能的)箭启。
另外,MySQL對幾乎全部schema操作都會完全重寫表,增加或刪除列會花費(fèi)一定時(shí)間,和行的數(shù)量成比例壕翩。在低速硬件上每百萬行數(shù)據(jù)可能要花一分鐘以上 -給幾百萬行數(shù)據(jù)的表添加幾列能鎖定你的站點(diǎn)10分鐘以上。
最后, MySQL對列名,表名和索引名有合理的長度限制,以及單一索引能覆蓋的所有列的組合大小也有限制傅寡。這意味著在其他后端上可能創(chuàng)建的索引,在MySQL上可能失敗放妈。
SQLite
SQLite只有非常少的內(nèi)置schema變更支持, 因此Django嘗試通過以下方法進(jìn)行模擬:
使用新的schema創(chuàng)建一個(gè)新表
表間數(shù)據(jù)復(fù)制
刪除舊表
新表重命名為舊表
這個(gè)過程通常工作的很好,但有可能比較慢并且偶爾會出現(xiàn)bug北救。不推薦你在生產(chǎn)環(huán)境上運(yùn)行和遷移SQLite,除非你非常清楚它的風(fēng)險(xiǎn)和限制; Django使用SQLite是為了讓開發(fā)者在他們的本機(jī)上開發(fā)不是那么復(fù)雜的項(xiàng)目,因此不需要一個(gè)完全的數(shù)據(jù)庫。
工作流
使用遷移是非常簡單的芜抒。變更你的模型 - 比如,添加一列或刪除一個(gè)模型 - 然后運(yùn)行makemigrations:
$ python manage.py makemigrationsMigrations for 'books': 0003_auto.py: - Alter field author on book
你的模型會被掃描并和當(dāng)前版本遷移文件中的模型進(jìn)行比較,然后生成一系列新的遷移文件珍策。確保閱讀輸出來看看makemigrations做的是不是你想要的- 這種方式并不完美,對于復(fù)雜的變更它也不能如你期望的那樣檢測出來。
一旦你有了這些新的遷移文件,你就可以將它們應(yīng)用到數(shù)據(jù)庫并確保它們?nèi)缙谕愎ぷ?
$ python manage.py migrateOperations to perform: Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes Apply all migrations: booksSynchronizing apps without migrations: Creating tables... Installing custom SQL... Installing indexes...Installed 0 object(s) from 0 fixture(s)Running migrations: Applying books.0003_auto... OK
命令分2步運(yùn)行;第一步,它同步不遷移的app (和之前版本提供的syncdb功能一樣),然后開始運(yùn)行所有沒有應(yīng)用的遷移宅倒。
一旦運(yùn)行了遷移,將遷移和模型變更在同一次提交中提交到你的版本控制系統(tǒng) - 這樣,當(dāng)其他開發(fā)者 when other developers (或者你的生產(chǎn)服務(wù)器) 檢出代碼時(shí),他們能同時(shí)獲得變更的模型和遷移腳本攘宙。
版本控制
因?yàn)檫w移腳本存放在版本控制系統(tǒng)中,偶爾你會碰到這樣的情況,當(dāng)你和另一個(gè)開發(fā)者同時(shí)提交了同一個(gè)app的遷移腳本,導(dǎo)致2個(gè)遷移腳本有同樣的順序號。
不用擔(dān)心 - 順序號只是為了開發(fā)者引用,Django只關(guān)心不同名稱的遷移腳本拐迁。遷移在腳本中指定了它依賴的其他遷移腳本- 包括在同一個(gè)app上的之前的遷移,所以是可能檢測到這2個(gè)對同一個(gè)app的新的遷移不是有先后順序的(即有沖突的)蹭劈。
當(dāng)這種情況發(fā)生時(shí),Django會提示你并給你一些選項(xiàng)。如果你認(rèn)為這足夠安全, 它能自動的線性化的應(yīng)用這2個(gè)遷移线召。 如果不是,你需要自己去修改遷移腳本- 別擔(dān)心,這不難,下面的Migration files也會詳細(xì)解釋铺韧。
依賴
遷移是逐app進(jìn)行的,模型的表和關(guān)系可能過于復(fù)雜而不能在單一app上創(chuàng)建。當(dāng)進(jìn)行遷移時(shí)可能會要求其他東西也要運(yùn)行 - 例如,你在book app中添加一個(gè)外鍵指向authorsapp - 生成的遷移腳本就會包含一個(gè)authors中的遷移腳本的依賴缓淹。
這意味著當(dāng)你運(yùn)行遷移時(shí),authors遷移先運(yùn)行來創(chuàng)建這個(gè)ForeignKey引用的表,然后生成ForeignKey的列的遷移運(yùn)行并創(chuàng)建這個(gè)約束哈打。如果不是這樣,遷移會嘗試創(chuàng)建一個(gè)ForeignKey列指向一個(gè)還不存在的表,這時(shí)你的數(shù)據(jù)庫會拋出異常。
這種依賴行為影響的大多數(shù)遷移操作被限制到一個(gè)單一的應(yīng)用程序讯壶。限制到一個(gè)單一的應(yīng)用程序(無論是makemigrations或migrate)是一個(gè)最好的努力的承諾,但不是保證;任何需要使用其他應(yīng)用程序需要得到的正確的依賴關(guān)系料仗。
但是要注意,不遷移的應(yīng)用程序不能依賴于應(yīng)用程序的遷移,不遷移沒有依賴是很自然的。這意味著,一個(gè)不遷移的應(yīng)用程序不能有一個(gè)外鍵或多對多的關(guān)系指向一個(gè)遷移應(yīng)用程序;某些情況下可以工作,但是它最終會失敗伏蚊。
如果你使用可替換的模型(例如AUTH_USER_MODEL)時(shí)是很明顯的,因?yàn)槊總€(gè)使用可替換模型的app都需要進(jìn)行遷移,如果你不走運(yùn)的話立轧。隨著時(shí)間推移,越來越多的第三方應(yīng)用需要遷移,但同時(shí)你也可以自己進(jìn)行遷移(使用MIGRATION_MODULES存放app之外的模型),或者保持你的用戶模型不進(jìn)行遷移。
遷移腳本
遷移文件被存放為一種磁盤格式,這里稱之為“遷移腳本”丙挽。這些文件實(shí)際只是普通的Python文檔, 對象布局約定,聲明式風(fēng)格肺孵。
一個(gè)基本的遷移腳本看上去是這樣:
from django.db import migrations, modelsclass Migration(migrations.Migration): dependencies = [("migrations", "0001_initial")] operations = [ migrations.DeleteModel("Tribble"), migrations.AddField("Author", "rating", models.IntegerField(default=0)), ]
Django加載遷移腳本(作為一個(gè)Python模塊)時(shí)尋找一個(gè)django.db.migrations.Migration子類匀借。它檢測這個(gè)對象的4種屬性,只有2個(gè)在大多數(shù)時(shí)候使用:
依賴,一個(gè)遷移依賴的列表颜阐。
操作,一個(gè)定義了遷移如何進(jìn)行的Operation類的列表。
操作是關(guān)鍵,他們是一系列指示告訴django怎么進(jìn)行schema更新吓肋。django掃描它們并在內(nèi)存中構(gòu)建所有app的schema更新,用來生成對應(yīng)的SQL語句凳怨。
這些內(nèi)存中的結(jié)構(gòu)也用來找出模型與當(dāng)前遷移狀態(tài)的差異點(diǎn)。django運(yùn)行所有的變更,順序的,通過刷新內(nèi)存中的模型到你最后一次運(yùn)行makemigrations時(shí)的模型狀態(tài)是鬼。它通過使用這些模型與你的models.py文件做對比找出你所做的變更肤舞。
你很少需要手動編輯遷移腳本,但是需要的話也是完全有可能手寫的。一些更復(fù)雜的操作不能自動檢測到,只能通過手寫,所以當(dāng)需要編輯的時(shí)候也不要被嚇到均蜜。
自定義字段
你不能修改已經(jīng)遷移過的自定義字段的位置參數(shù)的數(shù)量,會導(dǎo)致TypeError異常李剖。老的遷移會用老的簽名調(diào)用修改的__init__方法。所以如果你需要一個(gè)新的參數(shù),請創(chuàng)建一個(gè)keyword argument并且在構(gòu)造函數(shù)中加上assert?kwargs.get('argument_name')?is?not?None之類的語句囤耳。
增加遷移到應(yīng)用中
增加遷移到新app中是很直接的 - 它們預(yù)置為接受遷移,所以當(dāng)做出變化后只需要運(yùn)行makemigrations篙顺。
如果你的app已經(jīng)有模型和數(shù)據(jù)庫表,而且沒有使用過遷移 (例如,你在之前的django版本上創(chuàng)建的),你需要轉(zhuǎn)換到使用遷移模式;下面是一個(gè)簡單的過程:
$ python manage.py makemigrations your_app_label
它將會為你的app初始化遷移∨忌郑現(xiàn)在,當(dāng)你運(yùn)行migrate,django能檢測到你已經(jīng)初始化遷移,而那些它想創(chuàng)建的表已經(jīng)存在,它就會標(biāo)記遷移已經(jīng)應(yīng)用。
注意這能正常工作需要2個(gè)條件:
生成表之后沒有變更過模型德玫。為了遷移能工作,需要先做初始化遷移工作,然后再變更模型,因?yàn)閐jango和遷移腳本做變更對比,而不是數(shù)據(jù)庫匪蟀。
沒有手動修改過數(shù)據(jù)庫 - django不能檢測到你的數(shù)據(jù)庫和模型的不匹配,當(dāng)使用遷移修改這些表時(shí)只能得到error。
模型演變
當(dāng)你運(yùn)行遷移, django通過存儲在遷移腳本中的模型歷史版本來運(yùn)行宰僧。如果你使用RunPython操作運(yùn)行Python代碼,或者你在數(shù)據(jù)庫routers上添加了allow_migrate方法, 你的模型將被暴露給這些版本材彪。
因?yàn)椴荒苄蛄谢我獾腜ython代碼,這些歷史版本模型不會包含自定義方法和manager。它們,包含同樣的字段,關(guān)系和元數(shù)據(jù)?(也版本化了,所以可能和你當(dāng)前的不一致)琴儿。
警告
這意味著當(dāng)你在遷移時(shí)不能訪問模型對象上的自定義save()方法,也不能有任何自定義的構(gòu)造或?qū)嵗椒?請仔細(xì)規(guī)劃段化。
另外,模型的基類僅僅被存儲為指針,所以如果遷移中包含對它們的引用你需要一直保留這些基類。好的方面而言,基類中的方法和managers能正常的繼承,所以如果你確實(shí)需要訪問它們你可以選擇把它們移到基類中造成。
數(shù)據(jù)遷移
當(dāng)變更數(shù)據(jù)庫schema時(shí),你也可以結(jié)合schema使用migrations變更數(shù)據(jù)庫中的數(shù)據(jù)穗泵。
變更數(shù)據(jù)的遷移被稱為“data migrations”;它們最好寫成單獨(dú)的腳本,放在你的架構(gòu)遷移腳本旁邊。
django不會自動為你創(chuàng)建數(shù)據(jù)遷移腳本,它只會生成架構(gòu)遷移,但是寫這些數(shù)據(jù)遷移也不是很難谜疤。django中的遷移腳本由?Operations組成,數(shù)據(jù)遷移的主要操作是RunPython佃延。
開始時(shí),生成一個(gè)空的遷移腳本(django會放置文件在正確的地方,建議一個(gè)文件名稱,并添加依賴):
python manage.py makemigrations --empty yourappname
然后,打開文件;它看起來像這樣:
# -*- coding: utf-8 -*-from django.db import models, migrationsclass Migration(migrations.Migration): dependencies = [ ('yourappname', '0001_initial'), ] operations = [ ]
現(xiàn)在,你所需要做的就是創(chuàng)建一個(gè)新的函數(shù)讓RunPython調(diào)用。RunPython期望一個(gè)callable對象,有2個(gè)參數(shù) - 第一個(gè)是一個(gè)app registry,它含有你的模型的全部歷史變更信息,第二個(gè)是SchemaEditor,用來手動變更數(shù)據(jù)庫架構(gòu)(注意,這個(gè)可能和遷移自動檢測想沖突!)
讓我們寫一個(gè)簡單的腳本生成一個(gè)新字段name,它是first_name和last_name的組合值(我們需要意識到不是所有人都有 first 和 last name)夷磕。我們需要做的是使用歷史模型,迭代所有的行:
# -*- coding: utf-8 -*-from django.db import models, migrationsdef 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), ]
一旦完成了腳本,我們能正常運(yùn)行python?manage.py?migrate,數(shù)據(jù)遷移會和其他遷移一同完成履肃。
你也可以傳遞第二個(gè)callable 給RunPython?來運(yùn)行任何你想要的邏輯。如果這個(gè)callable被省略了,遷移后端會拋出異常坐桩。
如果你希望閱讀更多的高級遷移操作介紹,或者考慮能否自己寫,參考?migration operations reference尺棋。
合并遷移
你可以自由使用migrations不用考慮遷移數(shù)量。migration代碼被優(yōu)化成可以一次處理幾百個(gè)遷移而不會明顯變慢绵跷。然而,偶爾你需要將幾百次遷移變成少量遷移,這時(shí)你需要使用squashing膘螟。
Squashing是減少現(xiàn)存的大量遷移到一個(gè)(有時(shí)是幾個(gè))遷移的藝術(shù),代表了同樣的變更。
Django做到這個(gè)是通過收集所有現(xiàn)存的遷移腳本,抽起它們的操作,然后把它們放到一個(gè)序列中,對它們進(jìn)行一個(gè)優(yōu)化來減少序列的長度?- 例如,它知道CreateModel和DeleteModel操作相互抵消,它也知道AddField可以整合到CreateModel中碾局。
一旦操作序列被盡可能的減少 - 這個(gè)數(shù)量可能取決于你的模型相互纏結(jié)的程度和是否有RunSQL或RunPython操作 (這些都不能被優(yōu)化) - Django將把它們寫回到一套新的初始化遷移腳本中荆残。
這些腳本被標(biāo)記為取代之前的腳本 - 合并腳本,所以它們能夠和舊的腳本共存,Django能智能的在它們之中切換。如果你還處于合并遷移過程中,它會繼續(xù)使用原來的腳本直到合并腳本的最后一項(xiàng),然后切換到合并歷史版本,這樣新安裝時(shí)會只使用新的合并腳本而跳過所有老的腳本净当。
這保證了你能進(jìn)行合并而不會弄亂并非完全保持最新的生產(chǎn)系統(tǒng)内斯。推薦流程是進(jìn)行合并,保留老的腳本,提交和發(fā)布,等待所有系統(tǒng)都升級到新的版本(或者如果是第三方工程,保證你的用戶順序升級而不要跳過任何一步),然后刪除老的文件,提交和進(jìn)行下個(gè)版本開發(fā)。
命令是squashmigrations- 只需要傳遞app的label 和 你想合并的遷移腳本名稱,它就可以工作了:
$ ./manage.py squashmigrations myapp 0004Will squash the following migrations: - 0001_initial - 0002_some_change - 0003_another_change - 0004_undo_somethingDo you wish to proceed? [yN] yOptimizing... Optimized from 12 operations to 7 operations.Created new squashed migration /home/andrew/Programs/DjangoTest/test/migrations/0001_squashed_0004_undo_somthing.py You should commit this migration but leave the old ones in place; the new migration will be used for new installs. Once you are sure all instances of the codebase have applied the migrations you squashed, you can delete them.
注意模型依賴在Django中可能會非常復(fù)雜,合并可能導(dǎo)致優(yōu)化后的遷移不能功能或不能運(yùn)行像啼。這種情況下,你可以使用--no-optimize,不過請報(bào)告一個(gè)bug(file a bug report),告知模型細(xì)節(jié)和它們的關(guān)系,這樣我們可以針對它改善優(yōu)化器俘闯。
一旦你合并了你的遷移,你應(yīng)該和原遷移一起提交并發(fā)布變更到所有的你的運(yùn)行中的應(yīng)用上,確保它們運(yùn)行migrate并將變更保存到數(shù)據(jù)庫中。
完成之后,你需要將合并遷移腳本轉(zhuǎn)換成一個(gè)普通的初始化遷移腳本,通過:
刪除所有被代替的遷移腳本
在合并遷移腳本中的Migration類中刪除replaces參數(shù)(這是Django如何獲知他是合并腳本的方式)
注意
一旦你合并了遷移,你不能重復(fù)合并直到你把它完全轉(zhuǎn)換成一個(gè)普通的腳本忽冻。
序列化值
遷移腳本僅僅是包含了老的模型定義的Python文件 - 因此, django需要獲取模型的當(dāng)前狀態(tài)并把它們序列化輸出到一個(gè)文件真朗。
django能序列化大多數(shù),但還是有部分我們不能序列化成一個(gè)合法的Python表示 - 沒有相關(guān)的Python標(biāo)準(zhǔn)來說明一個(gè)值應(yīng)該怎么轉(zhuǎn)換成代碼 (repr()只能識別基本類型,也不能指定import路徑)。
django能序列化以下值:
int,long,float,bool,str,unicode,bytes,None
list,set,tuple,dict
datetime.date和datetime.datetime實(shí)例
decimal.Decimal實(shí)例
任意Django域
任意function或method引用(例如datetime.datetime.today)
任意class引用
任意有自定義deconstruct()方法的對象 (see below)
django 在 Python 3 能序列以下:
類body中使用的未綁定 methods ?(see below)
django不能序列以下類型:
任意 class 實(shí)例 (例如MyClass(4.3,?5.7))
Lambdas
因?yàn)開_qualname__只在Python 3中引入,django只能在Python 3中序列化以下pattern (類body中使用的未綁定 methods), Python 2中會序列化失敗:
class MyModel(models.Model): def upload_to(self): return "something dynamic" my_file = models.FileField(upload_to=upload_to)
如果你使用Python 2,我們建議你把upload_to 或者相似的接受callables參數(shù)的方法 (例如default)移到主module體中,而不是類體中僧诚。
增加一個(gè)deconstruct()方法
你可以讓django來序列化你的自定義類實(shí)例,只有給類一個(gè)deconstruct()方法遮婶。方法不需要參數(shù),需要返回一個(gè)包括3個(gè)東西的元組:(path,?args,?kwargs)秀菱。注意返回值不同與自定義域的deconstruct()方法,這個(gè)方法返回包含4項(xiàng)的元組。
path指向類的Python路徑,最后部分包含類名(例如myapp.custom_things.MyClass)蹭睡。如果你的類通過頂層模塊無法訪問,那么它不會被序列化衍菱。
args傳遞給類的__init__方法的位置參數(shù)的列表。列表中的參數(shù)本身也必須是支持序列化的肩豁。
kwargs傳遞給類的__init__方法的關(guān)鍵字參數(shù)的字典脊串。字典中的每個(gè)值都必須是支持序列化的。
django會為你的類的實(shí)例化寫入值,包括給定的參數(shù),和寫django字段引用的方法類似清钥。
因?yàn)槟愕念惖腸onstructor的參數(shù)本身會序列化,你可以從django.utils.deconstruct導(dǎo)入@deconstructible類裝飾器:
from django.utils.deconstruct import?aliyunzixun@xxx.com?MyCustomClass(object): def __init__(self, foo=1): ...
這個(gè)裝飾器加入了邏輯能捕獲和保存進(jìn)入構(gòu)造器的參數(shù),然后當(dāng)deconstruct()調(diào)用時(shí)精確的返回這些參數(shù)琼锋。
從South升級
如果你已經(jīng)使用South做過遷移,那么升級到使用django.db.migrations是非常簡單的:
確保所有的安裝應(yīng)用和它們的遷移狀態(tài)一致
刪除所有的編號遷移腳本,但不用刪除目錄或__init__.py- 同時(shí)確保你刪除了.pyc文件。
運(yùn)行python?manage.py?makemigrations祟昭。Django會發(fā)現(xiàn)這個(gè)空的遷移文件夾并且用新的格式生成新的初始化遷移腳本缕坎。
運(yùn)行python?manage.py?migrate。Django會發(fā)現(xiàn)初始化遷移要創(chuàng)建的表已經(jīng)存在,它會標(biāo)記為已應(yīng)用這些遷移篡悟。
完成了! 唯一不好的是如果你有一個(gè)外鍵循環(huán)引用,這種情況下,makemigrations會不止一次執(zhí)行初始化遷移,所以你需要像下面這樣標(biāo)記它為已經(jīng)應(yīng)用:
python manage.py migrate --fake yourappnamehere?庫/第三方應(yīng)用
如果你是庫或app維護(hù)員,希望能同時(shí)支持South (為Django 1.6和以下版本) 和 Django migrations (為1.7以上版本),你需要保留2套并行的遷移設(shè)置,每種一種格式谜叹。
為了達(dá)到這個(gè)目的,South 1.0會自動尋找South-format migrations,首先在south_migrations目錄中,在使用migrations之前,意味著用戶的項(xiàng)目會透明的使用正確的這套設(shè)置只要你把South migrations放在south_migrations目錄中,把Django migrations放在migrations目錄中。
以上是django 1.7 新的migration框架搬葬,取代south的內(nèi)容荷腊,更多?框架?的內(nèi)容,請您使用右上方搜索功能獲取相關(guān)信息