此文為本人原創(chuàng)拉一,最早發(fā)布于flask開(kāi)發(fā)的第五章關(guān)于創(chuàng)建遷移腳本的問(wèn)題(已解決) - cocode.cc。內(nèi)容并不完善旧乞,持續(xù)更新蔚润,可隨意轉(zhuǎn)載。轉(zhuǎn)載請(qǐng)標(biāo)明出處尺栖。
分享一點(diǎn)經(jīng)驗(yàn)嫡纠,主要是自己的理解,希望能有所幫助。千辛萬(wàn)苦部署好的數(shù)據(jù)庫(kù)除盏,就不為了答題一一驗(yàn)證了叉橱,全憑記憶回答,有不對(duì)的地方歡迎指出者蠕,會(huì)及時(shí)修改窃祝。
以下內(nèi)容以執(zhí)行文件名為manage.py
舉例,請(qǐng)自行調(diào)整踱侣。
-
影響
migrate
的是數(shù)據(jù)庫(kù)的結(jié)構(gòu)粪小。- 比方說(shuō)你的
User
類中添加了一個(gè) Column -nickname
,那么在保存 Model 之后建議執(zhí)行python manage.py db migrate -m "add nickname
抡句; - 而給 table 加入了新的方法探膊,例如
def change_nick_name()
,是不需要migrate
的玉转。如果migrate
突想,結(jié)果也是No change
; - 這一點(diǎn)可以留意一下究抓,比較保險(xiǎn)的辦法是覺(jué)得有必要的時(shí)候就嘗試一下
migrate
猾担,反正No changes
對(duì)你的遷移也沒(méi)有影響。
- 比方說(shuō)你的
-
在創(chuàng)建本地?cái)?shù)據(jù)庫(kù)的時(shí)候刺下,不要在
py shell
環(huán)境下執(zhí)行db.create_all()
- 請(qǐng)使用
python manage.py db init
,python manage.py db upgrade
來(lái)創(chuàng)建本地?cái)?shù)據(jù)庫(kù)绑嘹。 - 通常我會(huì)模仿書(shū)本上在上面兩條指令之間再做一次
migrate
,但經(jīng)驗(yàn)告訴我橘茉,結(jié)果好像都是No changes
工腋,畢竟,我init
之后沒(méi)有做過(guò)調(diào)整啊畅卓。 -
init
指令會(huì)根據(jù)Model.py
中的結(jié)構(gòu)創(chuàng)建遷移文件夾migrations
擅腰,而upgrade
會(huì)根據(jù)migrations
下的內(nèi)容,通過(guò)config.py
在找到正確的位置翁潘,并創(chuàng)建SQL趁冈,并在SQL中創(chuàng)建一個(gè)名為versions
的table來(lái)存放和遷移文件夾中相同的版本號(hào)。(重要) - 在開(kāi)始的嘗試中拜马,特別是往heroku上部署的過(guò)程中渗勘,經(jīng)常會(huì)遇到許多數(shù)據(jù)庫(kù)的坑,如果實(shí)在走投無(wú)路俩莽,又確定是數(shù)據(jù)庫(kù)遷移問(wèn)題旺坠,并且無(wú)法優(yōu)雅地解決。你需要做的就是以下幾步:
(1). 休息一下扮超,我知道你很累了
(2). 執(zhí)行python manage.py db shell
取刃,在py shell
環(huán)境下執(zhí)行drop_all()
蹋肮;或者直接刪了你的原有數(shù)據(jù)庫(kù)。
(3). 按照本段前面的提示重新創(chuàng)建本地SQL
(4).drop_all()
或者刪除并重新指定遠(yuǎn)端數(shù)據(jù)庫(kù)
(5). 執(zhí)行heroku run python manage.py db deploy
(假設(shè)你部署在heroku上璧疗,并已經(jīng)完成了deploy的定義)
(6). 現(xiàn)在你的遠(yuǎn)端和本地?cái)?shù)據(jù)庫(kù)的版本是相同的了括尸。
- 請(qǐng)使用
-
如果本地使用sqlite作為數(shù)據(jù)庫(kù),千萬(wàn)不要從
model.py
中刪除column
病毡!- 這一點(diǎn)非常重要,因?yàn)楦鶕?jù)我查到到資料顯示屁柏,sqlite是沒(méi)有“刪除行”這一個(gè)選項(xiàng)的啦膜。如果你刪除了某個(gè)
column
,這一操作能被migrate
正確記錄淌喻,但是在你upgrade
的時(shí)候就會(huì)報(bào)錯(cuò)僧家。然后想要還原migrate版本?抱歉裸删,我不會(huì)……(歡迎朋友們指導(dǎo)一下八拱,謝謝!)
- 這一點(diǎn)非常重要,因?yàn)楦鶕?jù)我查到到資料顯示屁柏,sqlite是沒(méi)有“刪除行”這一個(gè)選項(xiàng)的啦膜。如果你刪除了某個(gè)
-
部署到遠(yuǎn)端時(shí)涯塔,請(qǐng)確認(rèn)你又
versions
文件夾- 我不確定
init
會(huì)不會(huì)有肌稻,在執(zhí)行migrate
指令時(shí),會(huì)更新versions
文件夾 - 如果沒(méi)有
versions
文件夾匕荸,遠(yuǎn)端部署的時(shí)候也會(huì)報(bào)錯(cuò)爹谭,請(qǐng)務(wù)必留意。
- 我不確定
-
理解每個(gè)遷移指令的含義
-
init
的作用是初始化遷移榛搔,創(chuàng)建migration
文件夾 -
migrate
的作用是根據(jù)model.py中的變化更新遷移诺凡,該指令會(huì)在migration/versions/
文件夾中新增一個(gè)版本文件,文件名為版本號(hào)践惑。打開(kāi)能夠看到對(duì)應(yīng)model.py文件腹泌,修改前后新遷移版本發(fā)生的變化。 -
update
會(huì)將遷移中最新版本的結(jié)構(gòu)應(yīng)用到數(shù)據(jù)庫(kù)中(例如添加新增的列)尔觉,并更新自動(dòng)創(chuàng)建的version
表中的版本號(hào)凉袱。該版本號(hào)與migration/versions/
文件夾中對(duì)應(yīng)。任何情況下穷娱,這兩個(gè)版本號(hào)不對(duì)應(yīng)都會(huì)導(dǎo)致出錯(cuò)绑蔫。
-
我的帖子與回答都會(huì)持續(xù)更新。如果您覺(jué)得有幫助泵额,煩請(qǐng)點(diǎn)個(gè)贊配深,這樣或許能幫到其它朋友。
如果我有誤導(dǎo)他人的地方嫁盲,請(qǐng)與我聯(lián)系篓叶,我會(huì)及時(shí)修改烈掠。謝謝!
如果有需要的朋友缸托,可以看看我的website左敌,希望對(duì)大家有所幫助。
關(guān)于網(wǎng)頁(yè)中已有的功能都可以和我交流俐镐,歡迎查找bug矫限,交流心得。謝謝佩抹!
(網(wǎng)站處于測(cè)試階段叼风,請(qǐng)勿保存重要信息,數(shù)據(jù)丟失概不負(fù)責(zé)棍苹,還請(qǐng)見(jiàn)諒无宿。)
辭職學(xué)習(xí)中,有工作機(jī)會(huì)歡迎與我聯(lián)系枢里,謝謝孽鸡!