Django South kullanarak taşıma geçmişini sıfırlamak için önerilen yaklaşım nedir?


153

Güney (0.7) ve Django (1.1.2) kullanarak birim testlerimde oldukça fazla zaman geçirmeye başlayan birkaç göç biriktirdim. Taban çizgisini sıfırlamak ve yeni bir taşıma kümesi başlatmak istiyorum. Güney dokümanlarını inceledim, her zamanki Google / Stackoverflow aramasını (ör. "Django south (sıfırla VEYA sil VEYA kaldır) taşıma geçmişi") yaptım ve belirgin bir şey bulamadım.

Düşündüğüm bir yaklaşım, Güney'i "kaldırarak" veya geçmişi manuel olarak "temizleyerek" (baştan db tablosunu temizle, geçiş dosyalarını taşıma direktöründen kaldırarak) "yeniden başlatmayı" ve sadece yeniden çalıştırmayı içerir.

./manage.py şema göçü southtut --başlangıç

Yani, kimse bunu daha önce yaptı ve bazı ipuçları / önerileri varsa, onlar büyük mutluluk duyacağız.


bazen elle eklemeniz __init__.pygerekirappname/migrations
laike9m

2
1.7'deki taşıma işlemlerini (yerleşik taşıma işlemiyle) nasıl sıfırlarsınız?
Timo

1
@Timo: docs.djangoproject.com/en/dev/topics/migrations/… bir yaklaşım olabilir. Ayrıca sadece göçlerinizi / dizinlerinizi kaldırabilir ve yeniden yayınlayabilirsiniz, ./manage.py makemigrationsancak yeni bir
db'den

Bence squashmigrationsdoğru cevap
Julio Marins

Yanıtlar:


121

EDIT - @andybak takip eden> kabul edilen cevaptan önce okumak önemlidir çünkü aşağıya bunun üzerine bir yorum koyuyorum

@Dominique: manage.py reset south ile ilgili önerileriniz tehlikelidir ve aşağıdaki @thnee tarafından belirtildiği gibi projede güneyi kullanan herhangi bir üçüncü taraf uygulaması varsa veritabanını yok edebilir. Cevabınız çok fazla oy verdiğinden, düzenleyebilir ve bu konuda en azından bir uyarı ekleyebilirseniz veya (hatta daha iyi) @hobs yaklaşımını yansıtmak için değiştirin (ki bu da uygun, ancak diğer uygulamaları etkiler) - teşekkürler! - chrisv 26 Mart '13 at 9:09

Kabul edilen cevap aşağıdaki gibidir:

İlk olarak, Güney yazarının cevabı :

Tüm dağıtımlarda aynı anda yapmaya özen gösterdiğiniz sürece, bununla ilgili herhangi bir sorun olmamalıdır. Şahsen ben yapardım:

    rm -r appname/migrations/ 
    ./manage.py reset south 
    ./manage.py convert_to_south appname 

(“ reset south” Kısmının TÜM uygulamalar için taşıma kayıtlarını temizlediğine dikkat edin , bu nedenle ya tüm uygulamalar için diğer iki satırı çalıştırdığınızdan veya seçici olarak sildiğinizden emin olun).

Sondaki convert_to_southçağrı yeni bir geçiş yapar ve sahte uygular (veritabanınızda zaten karşılık gelen tablolar olduğundan). İşlem sırasında tüm uygulama tablolarını bırakmanıza gerek yoktur.

Tüm bu gereksiz dev taşıma işlemlerinden kurtulmam gerektiğinde dev + üretim sunucumda yaptığım şey:

  1. Her iki tarafta da aynı DB şemasına sahip olduğumuzdan emin olun
  2. her iki taraftaki her taşıma klasörünü sil
  3. run ./manage.py sıfırlama güney (yazıdan söylendiği gibi) her iki tarafta = güney masayı temizler *
  4. her iki tarafta da ./manage.py convert_to_south komutunu çalıştırın (0001 geçişi sahtekarlığı )
  5. sonra yeniden taşıma yapmaya başlayabilir ve sunucumdaki taşıma klasörlerini itebilirim

* diğerleri arasında yalnızca bir uygulamayı temizlemek istiyorsanız, south_history tablonuzu düzenlemeniz ve yalnızca uygulamanızla ilgili girişleri silmeniz gerekir.


2
Sadece kayıt için, Güney yazarının yanıtı şöyleydi: Tüm dağıtımlarda aynı anda yapmaya özen gösterdiğiniz sürece, bununla ilgili herhangi bir sorun olmamalıdır. Şahsen ben yaparım: rm -r appname / migrations / ./manage.py sıfırlama güney ./manage.py convert_to_south appname ("Güney sıfırlama" bölümünün TÜM uygulamalar için taşıma kayıtlarını temizlediğine dikkat edin. diğer iki satır için tüm uygulamalar veya silme seçimi).
Adriaan Tijsseling

2
Ayrıca tabloları manage.py schemamigration app name --initialbırakırsanız, convert_to_south yerine ihtiyacınız olduğunu unutmayın.
Adriaan Tijsseling

7
Django 1.5'ten itibaren "reset" yönetim komutu gitti. Bunun yerine, kabaca benzer bir şey yapmak isteyeceksiniz south.models.MigrationHistory.objects.all().delete().
Andrew

13
@Dominique: ilişkin Önerilerin manage.py reset southolan tehlikeli ve veritabanı yok edebilir projede güney kullanarak herhangi bir üçüncü taraf uygulamalar varsa aşağıdaki @thnee tarafından sivri out gibi. Cevabınız çok fazla oy verdiğinden, düzenleyebilir ve bu konuda en azından bir uyarı ekleyebilirseniz veya (hatta daha iyi) @hobs yaklaşımını yansıtmak için değiştirin (ki bu da uygun, ancak diğer uygulamaları etkiler) - teşekkürler!
chrisv

3
Bu neden bu kadar yüksek oranda değerlendirildi? South_migrationhistory tablonuzu neredeyse ASLA tamamen silmemelisiniz. Bu, bağımlı uygulamaları dokunmak istemediğiniz taşıma işlemleriyle tamamen bertaraf eder. Hob'in cevabı doğru.
Cerin

188

Çok uzun süren geçişleri seçerek (yalnızca bir uygulama için) sıfırlamanız gerekiyorsa, bu benim için çalıştı.

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

El ile herhangi restore etmeyi unutmayın bağımlılıkları gibi satırlar ekleyerek diğer uygulamalarda depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))da hiç <app-dir>/migrations/0001_initial.pyadil aşağıya göç sınıfında birinci özelliği olarak, dosyaya class Migration(SchemaMigration):.

Bu SO cevabına./manage.py migrate <app-name> --fake --delete-ghost-migrations göre başka ortamlarda da yapabilirsiniz . Tabii eğer sahte silme veya sahte el gibi göç ile herhangi sol üzerinde db tabloları silmeniz gerekir bu .migrate zero

Daha nükleer bir seçenek, ./manage.py migrate --fake --delete-ghost-migrationscanlı dağıtım sunucusunda ve ardından bir [my] sqldump. Ardından, taşınan, tamamen doldurulmuş db'ye ihtiyaç duyduğunuz ortamlarda [my] sql'e dökülen boru. Güney kutsallığı biliyorum, ama benim için çalıştı.


2
Gerçekten istediğim şey "gospel gibi models.py al ve beni o noktadan sonra temiz kıl". Böylece, sıfırdan bir dağıtım ayarlama veya mevcut bir dağıtımdan çalışma yeteneği korunur.
Bryce

1
Bu böyle yapar.
ocak

2
@hobs Bir DependsOnUnknownMigrationsüre yeni ilk geçişi taklit ediyordum . Yorumunuz sayesinde, depends_onbu uygulamaya atıfta bulunduğu yerde ifadeyi güncellemem gerektiğini anlayabilirim . Bu gerçekten en iyi cevap. Teşekkürler! :)
manu

55

Dominique Guardiola ve ocakların cevapları sayesinde zor bir problemi çözmeme yardımcı oldu. Bununla birlikte, çözümle ilgili birkaç sorun var, işte benim üstlenmem.

Kullanımı manage.py reset southise iyi bir fikir değil Eğer varsa üçüncü taraf uygulamalarını Güney kullanır, örneğin django-cms(temelde her şey Güney kullanır).

reset south yüklediğiniz tüm uygulamalar için tüm taşıma geçmişini siler.

Şimdi en son sürümüne yükselttiğinizi django-cms, bunun gibi yeni taşıma işlemleri içereceğini düşünün 0009_do_something.py. Eğer kalmadan bu göç çalıştırmayı denediğinizde Güney mutlaka kafası karışacaktır 0001yoluyla 0008göç tarihinin.

Yalnızca bakımını yaptığınız uygulamaları seçerek sıfırlamak çok daha iyi / güvenlidir .


Her şeyden önce, uygulamalarınızın diskteki taşıma işlemleri ile veritabanında yürütülen taşıma işlemleri arasında herhangi bir desync olmadığından emin olun. Aksi takdirde baş ağrısı olacaktır.

1. Uygulamalarım için taşıma geçmişini sil

sql> delete from south_migrationhistory where app_name = 'my_app';

2. Uygulamalarım için taşıma işlemlerini silin

$ rm -rf my_app/migrations/

3. Uygulamalarım için yeni ilk taşıma işlemleri oluşturma

$ ./manage.py schemamigration --initial my_app

4. Sahte uygulamalarım için ilk taşıma işlemlerini yürütür

Bu, geçişleri south_migrationhistorygerçek tablolara dokunmadan ekler :

$ ./manage.py migrate --fake my_app

Adım 3 ve 4 aslında sadece daha uzun bir varyantı manage.py convert_to_south my_app, ama bu ekstra kontrol, üretim veritabanını değiştirmek gibi hassas bir durumda tercih ederim.


2
Bulduğum sorunlara ilişkin düzeltmeleri dahil etmek için cevabımı düzenledim (sadece cevabınıza dayanarak onları tahmin ederek) ve milyonlarca satır içeren bir üretim veritabanında test ettim.
ocaklar

2
Yaptığımız şey bu. 4. adımda --delete-ghost-migrations seçeneğini kullanırsanız, 1. adımı dışarıda bırakabilirsiniz.
13'e

./manage.py migrate --fakeBekleyen taşıma işlemi olan diğer uygulamaları taklit etmek istemiyorsanız uygulama adlarını açıkça belirtmelisiniz .
wadim

2
@wadim Bu nedenle adım 0: "diskteki taşıma işlemleri ile veritabanında yürütülen taşıma işlemleri arasında desync olmadığından emin olun".
thnee

@ sağa. Muhtemelen 0. adımda yüklü tüm uygulamalara atıfta bulunduğunuzdan bahsetmeniz gerekir. 0 adımını gerçekleştirmenin kolay bir yolunu biliyor musunuz?
wadim

7

Thnee gibi (cevabına bakın), burada başka bir yerde alıntılanan Güney yazarının (Andrew Godwin) önerisine daha yumuşak bir yaklaşım uyguluyoruz ve dağıtım sırasında kod tabanı ile yaptığımız işi veritabanına yaptığımızdan ayırıyoruz , çünkü dağıtımların tekrarlanabilir olması gerekiyor:

Kodda ne yapıyoruz:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

Bu kod dağıtıldıktan sonra veritabanına ne yapıyoruz

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

Ben sadece aynı şeyi yaptım, ama --delete_ghoist-migrations kullanmak yerine, veritabanı girişlerini el ile silmek düşünüyorum. Yolunuz biraz daha hoş.
wobbily_col

1

Sadece dev makinede çalışıyorsanız, Dominique'nin önerdiği şeyi yapan bir yönetim komutu yazdım.

http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

Güney yazar önerisinin aksine, bu, güney kullanan diğer yüklü uygulamaları ZARARLAMAYACAKTIR.


Ve yazarın aksine, istediğiniz, eğer tutmak (yani iyi göç tarihi kadar uygulamasını sıfırlamak, ancak gerçek göçler tutmak istiyorum) göçler mevcut, o zaman bu deneyebilirsiniz: goo.gl/0ZnWm
mgalgs

1

Aşağıda yalnızca tüm uygulamaları sıfırlamak istiyorsanız kullanılır. Lütfen bu çalışmadan önce tüm veritabanlarınızı yedekleyin. Ayrıca, varsa dosyalarınıza bağımlı_onunuzu not edin .

Bir kez:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

Zorlamadan önce projenizi önyüklemeyi test edin. Ardından, her yerel / uzak makine için aşağıdakileri uygulayın:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

Yeniden dahil etmek istediğiniz her uygulama için ilk (3) işlemi yapın . Sıfırla (6) öğesinin yalnızca geçiş geçmişini sileceğini, bu nedenle kitaplıklara zarar vermeyeceğini unutmayın. Sahte taşıma işlemleri (7), yüklenen tüm 3. taraf uygulamaların taşıma geçmişini geri koyacaktır.


0

gerekli dosyayı uygulama klasöründen sil

örnek yolu

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

wiki - benim uygulamam

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.