在開發過程中,由于需求變更或者自我重構,需要清理migrations,以保持代碼整潔和后續的可維護性。
場景一
不考慮數據庫數據表,可以完全清空數據庫里面的表的數據。
步驟:
刪除所有migrations
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete
刪除數據庫的相關表
python manage.py makemigrations yourappname
python manage.py migrate yourappname
場景二
保留原有數據表的情況
這個情況是開發中最為常見的,也是操作起來稍微復雜一點的情況,但是只要遵循下面的操作步驟,就不會引發任何錯誤:
1.檢查migrations文件夾下面的修改記錄文件是否與數據庫保持一致,如若我們執行這個命令
python manage.py makegrations
執行結果顯示:
No changes detected
那我們就可以繼續執行下面的步驟
2.查看當前項目下所有APP對應的已經生效的(已經成功執行的)migration文件,命令如下:
python manage.py showmigrations
結果如下圖所示,前面的[x]表示已經執行過的文件,如:imooc這個APP下執行過兩次操作
admin[X] 0001_initial[X] 0002_logentry_remove_auto_add
auth[X] 0001_initial[X] 0002_alter_permission_name_max_length[X] 0003_alter_user_email_max_length[X] 0004_alter_user_username_opts[X] 0005_alter_user_last_login_null[X] 0006_require_contenttypes_0002[X] 0007_alter_validators_add_error_messages[X] 0008_alter_user_username_max_length
contenttypes[X] 0001_initial[X] 0002_remove_content_type_name
imooc[X] 0001_initial[X] 0002_auto_20190122_0929
sessions[X] 0001_initial
3.重置你的APP的操作,使它們恢復到沒有執行的狀態,這里注意一下fake前面的符號,是兩個“-”,另外,imooc是APP的名字,記得將它替換成你的APP名字。還有一點就是不要直接復制,要手敲到終端才不會因格式問題而產生錯誤。fake參數該怎樣理解呢?fake是假裝的意思,在這里我們可以理解為假設我們將這些操作設置為沒有執行的狀態,而不是他們真的沒有執行!
python manage.py migrate --fake imooc zero
結果如下,則顯示重置成功
(wprkplace) D:\PythonProject\learn>python manage.py migrate --fake imooc zero
Operations to perform:Unapply all migrations: imooc
Running migrations:Rendering model states... DONEUnapplying imooc.0005_hua... FAKEDUnapplying imooc.0004_xiao... FAKEDUnapplying imooc.0003_ming... FAKEDUnapplying imooc.0002_auto_20190122_0929... FAKEDUnapplying imooc.0001_initial... FAKED
然后我們可以再次執行showmigrations的命令,查看一下各個操作的狀態
(wprkplace) D:\PythonProject\learn>python manage.py showmigrations
admin[X] 0001_initial[X] 0002_logentry_remove_auto_add
auth[X] 0001_initial[X] 0002_alter_permission_name_max_length[X] 0003_alter_user_email_max_length[X] 0004_alter_user_username_opts[X] 0005_alter_user_last_login_null[X] 0006_require_contenttypes_0002[X] 0007_alter_validators_add_error_messages[X] 0008_alter_user_username_max_length
contenttypes[X] 0001_initial[X] 0002_remove_content_type_name
imooc[ ] 0001_initial[ ] 0002_auto_20190122_0929[ ] 0003_ming[ ] 0004_xiao[ ] 0005_hua
sessions[X] 0001_initial
可以看到imooc這個APP下面的操作全部重置為沒有執行的狀態,[x]變成了[ ],注意是假設它沒有執行!
4.然后放心大膽地刪除migrations文件夾下面,除了__init__.py文件,的所有的帶有序號的py文件,包括pycache文件夾!
5.執行下面的命令,再次為這個APP 生成 0001_initial.py 之類的文件
python manage.py makemigrations
提示如下則為成功
(wprkplace) D:\PythonProject\learn>python manage.py makemigrations
Migrations for 'imooc':imooc\migrations\0001_initial.py:- Create model Hua- Create model Ming- Create model Post- Create model Tag- Create model Test- Create model Xiao
6.執行下面的命令,使剛剛生成的0001_initial.py文件記錄到django_migrations數據表中,這個表是django自動生成的,用于記錄每次執行的數據庫修改操作,表中有四個字段,name和app是對應的關系,意為某某APP下的某某操作。
python manage.py migrate --fake-initial
結果如下即為成功
(wprkplace) D:\PythonProject\learn>python manage.py migrate --fake-initial
Operations to perform:Apply all migrations: admin, auth, contenttypes, imooc, sessions
Running migrations:Applying imooc.0001_initial... FAKED
如果你再去看一下django_migrations這個表,你會發現這個表添加了一條記錄,一般來說如果我們真的執行了數據庫的修改操作才會生成這樣一條記錄,但是我們用了fake這個“假裝”的操作,所以其實僅僅是添加了一條記錄而已,并沒有實際修改數據表,也就是這樣,完成了migrations文件夾的重置!
?
?
需要保留數據里面的數據,這種場景最為常見,只改結構不改數據
步驟:
使用migrate命令回滾0001_initial的migration history,回滾到最初
python manage.py migrate --fake yourappname zero
重新生成0001_initial,如果能保證已有0001_initial已是最新的,可跳過此步
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete
python manage.py makemigrations yourappname
在數據庫中生成新的0001_initial記錄
python migrate --fake-initial yourappname
另外,對于已經長期運行的項目,為了保留歷史重大版本,不建議回到最初的版本,不利于版本控制。
如果中間有報錯:
Django Table xxx already exist
python manage.py migrate --fake appname