2014-05-20 109 views
87

南方已經有類似的問題了,但是我已經用Django 1.7開始了我的項目,並沒有使用South。如何簡化Django 1.7中的遷移?

在開發過程中,已經創建了很多遷移,但是該軟件尚未發佈,並且不存在必須遷移的數據庫。因此,我想重置遷移,就好像我當前的模型是原始模型並重新創建所有數據庫。

推薦的方法是什麼?

編輯:從Django 1.8開始,有一個名爲squashmigrations的新命令,它或多或少的解決了這裏描述的問題。

+0

重置遷移意味着什麼?撤消它? –

回答

35

在Django 1.7版本的遷移中,過去在南方的重置功能已經被刪除,以支持「擠壓」遷移的新功能。這應該是保持遷移數量的好方法。

https://docs.djangoproject.com/en/dev/topics/migrations/#squashing-migrations

如果你仍然想真正從頭開始我以爲你仍然可以通過清空遷移表和刪除之後,你會再次運行makemigrations的遷移。

+2

除了清空遷移表之外,我將如何「移除遷移」?我會刪除整個文件夾還是僅刪除00X _ *。py文件? –

+0

與南你可以刪除當您再次運行makemigrations時將被重新創建的migrations文件夾。我認爲這對Django 1.7 – tijs

+4

的工作原理是一樣的。在Django 1.7中,如果你不小心刪除了遷移文件夾,如果你的模型是另一個'raise KeyError(「Migration%s依賴關係引用不存在的父節點%r」%(migration,parent))的孩子,它可能會引發異常。 ' – Algorithmatic

2

如果您不關心以前的遷移,那麼只需刪除migrations /目錄中的所有遷移呢?您將從頭開始遷移序列,將您當前的模型作爲參考,就好像您現在已經編寫了整個模型一樣。

如果你不相信我足夠的刪除,然後嘗試將它們移走。

+0

保持舊遷移的意義何在?當我試圖從django 1.6升級到1.8時,我的問題就出現了。 – Jay

+0

遷移只是您對數據庫所做更改的跟蹤記錄。當我的遷移鏈停止工作時,我不止一次採納過vokiman的建議。 –

7

假設這是你的項目結構,

project_root/ 
    app1/ 
     migrations/ 
    app2/ 
     migrations/ 
    ... 
    manage.py 
    remove_migrations.py 

你可以從上面的指示,刪除所有遷移文件的地方運行腳本remove_migrations.py。

#remove_migrations.py 
""" 
Run this file from a Django =1.7 project root. 
Removes all migration files from all apps in a project. 
""" 
from unipath import Path 

this_file = Path(__file__).absolute() 
current_dir = this_file.parent 
dir_list = current_dir.listdir() 

for paths in dir_list: 
    migration_folder = paths.child('migrations') 
    if migration_folder.exists(): 
     list_files = migration_folder.listdir() 
     for files in list_files: 
      split = files.components() 
      if split[-1] != Path('__init__.py'): 
       files.remove() 

如果您有一個精心設計的項目,手動刪除會很累人。這節省了我很多時間。刪除遷移文件是安全的。我已經做了這麼多次,但沒有遇到任何問題。

但是,當我刪除遷移文件夾時,makemigrationsmigrate沒有爲我創建文件夾。該腳本確保遷移文件夾的__init__.py保持放置狀態,只刪除遷移文件。

+0

您可以刪除遷移文件夾並用空的__init__.py重新創建它們(例如'touch migrations/__ init __。py') – hobs

0

cd到src目錄 cd /path/to/src

刪除遷移目錄 rm -rf your_app/migrations/

注意,這對於每個應用程序進行單獨

遷移 python3.3 manage.py migrate

,如果你想重新開始 python3.3 manage.py makemigrations your_app

131

我明白了。我只是想到了這一點,這是很好的。

./manage.py migrate --fake <app-name> zero 
+5

這是一個很好的答案。只是刪除遷移不會消除有缺陷的遷移造成的任何損壞。這實際上清理了石板並讓你重新開始。 – rogueleaderr

+1

要這樣做,你是否也需要刪除編號的遷移文件? – MrColes

+15

如果你詳細說明一下,這應該是被接受的答案。 –

20

我剛剛有同樣的問題。 這是我的解決方法。

#!/bin/sh 
echo "Starting ..." 

echo ">> Deleting old migrations" 
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete 
find . -path "*/migrations/*.pyc" -delete 


# Optional 
echo ">> Deleting database" 
find . -name "db.sqlite3" -delete 

echo ">> Running manage.py makemigrations" 
python manage.py makemigrations 

echo ">> Running manage.py migrate" 
python manage.py migrate 

echo ">> Done" 

find命令:http://unixhelp.ed.ac.uk/CGI/man-cgi?find

+12

這會刪除數據,而不僅僅是遷移 – hobs

+2

你也應該刪除.pyc文件 – shalbafzadeh

+0

今天救了我一命。 :) –

4

我嘗試不同的命令和一些問題的答案幫助我。在我的情況下,只有這個序列修復了MYAPP中遷移中的兩個中斷依賴關係,並清理了從頭開始的所有過去的遷移。

在執行此操作之前,請確保數據庫已同步(例如,不要在此處添加新的模型字段或更改Meta選項)。

rm -Rf MYAPP/migrations/* 
python manage.py makemigrations --empty MYAPP 
python manage.py makemigrations 
python manage.py migrate --fake MYAPP 0002 

其中0002是最後一個makemigrations命令返回的遷移編號。

現在您可以正常運行makemigrations/migrate,因爲遷移0002已存儲但未反映在已同步的數據庫中。

+0

在上面提到的所有解決方案中,只有這對我來說沒有問題,並且沒有刪除數據庫。 –

6
  1. 刪除文件: delete_migrations.py(在PRJ的根):
import os 

for root, dirs, files in os.walk(".", topdown=False): 
    for name in files: 
     if '/migrations' in root and name != '__init__.py': 
      os.remove(os.path.join(root, name)) 
  • DELETE FROM django_migrations Where app in ('app1', 'app2');

  • 。 /manage.py makemigrations

  • ./manage.py遷移--fake

  • 或者,您可以從所有這一切

    +0

    我必須指定'./manage.py makemigrations'的應用程序名稱才能正常工作,例如:'./manage.py makemigrations orders alerts' – Salami

    0

    如果你在開發模式下,你只是想重置的一切(數據庫寫遷移,遷移等等),我使用這個基於Abdelhamid Ba的答案的腳本。這將清除數據庫(Postgres的)的表,刪除所有遷移文件,重新運行遷移和負載我最初的燈具:

    #!/usr/bin/env bash 
    echo "This will wipe out the database, delete migration files, make and apply migrations and load the intial fixtures." 
    
    while true; do 
        read -p "Do you wish to continue?" yn 
        case $yn in 
         [Yy]*) make install; break;; 
         [Nn]*) exit;; 
         *) echo "Please answer yes or no.";; 
        esac 
    done 
    
    echo ">> Deleting old migrations" 
    find ../../src -path "*/migrations/*.py" -not -name "__init__.py" -delete 
    
    # Optional 
    echo ">> Deleting database" 
    psql -U db_user -d db_name -a -f ./reset-db.sql 
    
    echo ">> Running manage.py makemigrations and migrate" 
    ./migrations.sh 
    
    echo ">> Loading initial fixtures" 
    ./load_initial_fixtures.sh 
    
    echo ">> Done" 
    

    復位db.sql文件:

    DO $$ DECLARE 
        r RECORD; 
    BEGIN 
        -- if the schema you operate on is not "current", you will want to 
        -- replace current_schema() in query with 'schematodeletetablesfrom' 
        -- *and* update the generate 'DROP...' accordingly. 
        FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP 
         EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; 
        END LOOP; 
    END $$; 
    

    遷移sh文件:

    #!/usr/bin/env bash 
    cd ../../src 
    ./manage.py makemigrations 
    ./manage.py migrate 
    

    load_initial_fixtures.sh文件:

    #!/usr/bin/env bash 
    cd ../../src 
    ./manage.py loaddata ~/path-to-fixture/fixture.json 
    

    只要確保將路徑更改爲與您的應用相對應即可。我個人將這些腳本放在名爲project_root/script/local的文件夾中,而django的源文件位於project_root/src中。

    1

    一個簡單的方法是

    轉到每個應用程序並刪除遷移文件。

    然後轉到數據庫中的django-migrtaions表並截斷它(刪除所有條目)。

    之後,您可以再次創建遷移。

    +1

    在刪除遷移文件時,請確保不要刪除__init__文件。 – sprksh

    +0

    這真的幫了我。我刪除了所有遷移,從我的sqlite數據庫中刪除了表,但仍然無法進行遷移...但是,一旦我恢復了__init__.py文件**(doh),我就能夠再次進行遷移並獲得巡航。 @sprksh =救生員! – natureminded

    0

    在我的應用程序(手動)刪除各個「遷移」文件夾後,我跑:

    ./manage.py dbshell 
    delete from django_migrations; 
    

    然後,我想我可能只是做./manage.py makemigrations再生他們。但是,沒有檢測到變化。然後我嘗試一次指定一個應用程序:./manage.py makemigrations foo,./manage.py makemigrations bar。但是,這導致無法解決的循環依賴關係。

    最後,我跑了指定我所有的應用程序的單一makemigrations命令(排名不分先後):

    ./manage.py makemigrations foo bar bike orange banana etc 
    

    這一次,它的工作 - 循環依賴被自動解析(它創建額外的遷移文件,其中必要)。

    然後我就可以運行./manage.py migrate --fake並重新開始營業。