Django South를 사용하여 마이그레이션 기록을 재설정하는 데 권장되는 방법은 무엇입니까?


153

단위 테스트에서 꽤 많은 시간을 소비하기 시작한 South (0.7) 및 Django (1.1.2)를 사용하여 마이그레이션을 상당히 많이 수행했습니다. 기준을 재설정하고 새로운 마이그레이션 세트를 시작하고 싶습니다. South documentation을 검토하고 일반적인 Google / Stackoverflow 검색 (예 : "django south (재설정 또는 삭제 또는 제거) 마이그레이션 기록")을 수행했으며 명백한 내용을 찾지 못했습니다.

내가 생각한 한 가지 접근 방식은 남쪽을 "제거"하거나 기록을 수동으로 "삭제"(예 : db 테이블 지우기, 마이그레이션 디렉터에서 마이그레이션 파일 제거)하여 "다시 시작"하는 것입니다.

./manage.py schemamigration southtut --initial

따라서 누군가 전에이 작업을 수행했으며 몇 가지 팁 / 제안 사항이 있으면 크게 감사하겠습니다.


때로는 수동으로 추가 __init__.py해야합니다appname/migrations
laike9m

2
1.7에서 마이그레이션을 어떻게 재설정합니까 (내장 마이그레이션 사용)?
Timo

1
@Timo : docs.djangoproject.com/en/dev/topics/migrations/… 가 접근 할 수 있습니다. 또한 마이그레이션 / 디렉토리를 제거 하고 재발급 ./manage.py makemigrations할 수 있지만 새로운 데이터베이스에서 시작하지 않으면 나쁜 일이 발생합니다.
Jocelyn delalande

나는 squashmigrations정답 이라고 생각 합니다
Julio Marins

답변:


121

편집-@andybak 다음에 오는 대답>> 전에 답변을 읽는 것이 중요하기 때문에 아래에 주석을 달고 있습니다.

@Dominique : 남쪽에서 manage.py 재설정에 대한 조언은 위험하며 프로젝트에서 남쪽을 사용하는 타사 앱이 있으면 아래 @thnee가 지적한 경우 데이터베이스가 손상 될 수 있습니다. 귀하의 답변에 너무 많은 투표가 있기 때문에 편집하고 적어도 이것에 대해 경고를 추가하거나 @hobs 접근 방식을 반영하도록 변경하는 것이 좋을 것입니다. 다른 앱에 영향을 미침)-감사합니다! – chrisv 3 월 26 일 13시 9:09

허용되는 답변은 다음과 같습니다.

먼저 남쪽 저자의 답변 :

모든 배포에서 동시에주의를 기울이면 아무런 문제가 없어야합니다. 개인적으로, 나는 할 것입니다 :

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

" reset south"부분은 모든 앱의 마이그레이션 레코드를 지우므로 모든 앱에 대해 다른 두 줄을 실행하거나 선택적으로 삭제해야합니다.

마지막 convert_to_south호출은 데이터베이스에 이미 해당 테이블이 있으므로 새 마이그레이션을 만들고 가짜 적용합니다. 프로세스 중에 모든 앱 테이블을 삭제하지 않아도됩니다.

불필요한 dev 마이그레이션을 모두 제거해야 할 때 dev + 프로덕션 서버에서 수행하는 작업은 다음과 같습니다.

  1. 양쪽에 동일한 DB 스키마가 있는지 확인하십시오
  2. 양쪽의 모든 마이그레이션 폴더를 삭제하십시오.
  3. 양쪽에서 ./manage.py reset south (포스트에서 알 수 있듯이) = 남쪽 테이블을 지 웁니다.
  4. 양쪽에서 ./manage.py convert_to_south 를 실행하십시오 (0001 마이그레이션).
  5. 그런 다음 다시 시작하여 마이그레이션을 수행하고 서버에서 마이그레이션 폴더를 푸시 할 수 있습니다.

* 다른 앱 중에서 하나의 앱만 정리하려는 경우를 제외하고 south_history 테이블을 편집하고 앱에 대한 항목 만 삭제해야합니다.


2
기록을 위해 남한 저자의 답변은 다음과 같습니다. 모든 배포에서 동시에 처리하는 한이 문제는 발생하지 않습니다. rm -r appname / migrations / ./manage.py 남쪽으로 재설정 ./manage.py convert_to_south appname ( "남쪽으로 재설정"부분은 모든 앱의 마이그레이션 레코드를 지우므로주의하십시오. 모든 앱의 다른 두 줄 또는 선택적으로 삭제).
Adriaan Tijsseling

2
또한 테이블을 삭제하면 manage.py schemamigration app name --initialconvert_to_south 대신에 필요 합니다.
Adriaan Tijsseling

7
Django 1.5부터 "재설정"관리 명령이 사라졌습니다. 대신에 대략 같은 것을하고 싶을 것 south.models.MigrationHistory.objects.all().delete()입니다.
Andrew B.

13
@Dominique : 대한 귀하의 조언 manage.py reset south입니다 위험 하고 데이터베이스를 파괴 할 수 있습니다 프로젝트에서 남쪽으로 사용하는 타사 응용 프로그램이있는 경우 아래 @thnee에 의해 지적 아웃으로. 귀하의 답변에 너무 많은 투표가 있기 때문에 편집하고 적어도 이것에 대해 경고를 추가하거나 @hobs 접근 방식을 반영하도록 변경하는 것이 좋을 것입니다. 다른 앱에 영향을 미침)-감사합니다!
chrisv

3
왜 이렇게 높게 평가 되었습니까? south_migrationhistory 테이블을 거의 완전히 삭제해서는 안됩니다. 그것은 당신이 원하지 않는 마이그레이션으로 모든 의존적 인 응용 프로그램을 완전히 망칠 것입니다. 홉의 대답은 정답입니다.
Cerin

188

너무 오래 걸리는 마이그레이션을 선택적으로 (단 하나의 앱만) 재설정해야하는 경우이 방법이 효과적입니다.

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

수동으로 복원하는 것을 잊지 마세요 의존성 과 같은 행을 추가하여 다른 애플 리케이션에를 depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))당신에게 <app-dir>/migrations/0001_initial.py바로 아래에 마이그레이션 클래스의 첫 번째 속성으로 파일 class Migration(SchemaMigration):.

그런 다음 이 SO answer에./manage.py migrate <app-name> --fake --delete-ghost-migrations 따라 다른 환경에서 할 수 있습니다 . 물론 만약 당신이 가짜 삭제 또는 가짜 수동으로 같은 마이그레이션 어떠한 왼쪽 오버 DB 테이블을 삭제해야합니다 .migrate zero

더 강력한 옵션은 ./manage.py migrate --fake --delete-ghost-migrations라이브 배포 서버에서 [my] sqldump를 따르는 것입니다. 그런 다음 완전히 채워진 마이그레이션 된 db가 필요한 환경에서 해당 덤프를 [my] sql로 파이프하십시오. 나는 남쪽의 희생을 알고 있지만 나를 위해 일했습니다.


2
내가 정말로 원하는 것은 "models.py를 복음으로 받아 들여 그 시점부터 깨끗하게 해주는 것"입니다. 따라서 처음부터 배포를 설정하거나 기존 배포에서 작업 할 수있는 기능을 유지합니다.
Bryce

1
이것이하는 일입니다.
호브

2
@ hobs 나는 DependsOnUnknownMigration새로운 초기 마이그레이션을 가짜로 하는 동안 시간이 걸렸다 . 귀하의 의견에 감사드립니다 depends_on.이 앱을 언급하는 모든 곳 에서 진술을 업데이트해야 한다는 것을 알 수 있습니다. 이것이 실제로 가장 좋은 대답입니다. 감사! :)
manu

55

Dominique Guardiola와 호브의 답변 덕분에 어려운 문제를 해결할 수있었습니다. 그러나 솔루션에는 몇 가지 문제가 있습니다.

예를 들어 South를 사용하는 타사 앱 이있는 경우 (기본적으로 모든 것이 South를 사용 하는 경우)를 사용하는 manage.py reset south것은 좋지 않습니다 .django-cms

reset south 설치 한 모든 앱에 대한 모든 마이그레이션 기록을 삭제합니다.

이제 최신 버전으로 업그레이드하는 경우 django-cms와 같은 새로운 마이그레이션이 포함됩니다 0009_do_something.py. 마이그레이션 기록 을 0001통하지 않고 마이그레이션을 실행하려고하면 South가 반드시 혼동됩니다 0008.

유지 관리 하는 앱만 선택적으로 재설정하는 것이 훨씬 좋습니다 .


우선, 디스크 마이그레이션과 데이터베이스에서 실행 된 마이그레이션간에 앱이 동기화되지 않는지 확인하십시오. 그렇지 않으면 두통이 생길 것입니다.

1. 내 앱의 마이그레이션 기록을 삭제합니다.

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

2. 내 앱의 마이그레이션 삭제

$ rm -rf my_app/migrations/

3. 내 앱에 대한 새로운 초기 마이그레이션 생성

$ ./manage.py schemamigration --initial my_app

4. 내 앱의 초기 마이그레이션을 가짜로 실행

south_migrationhistory실제 테이블을 건드리지 않고 마이그레이션을 삽입합니다 .

$ ./manage.py migrate --fake my_app

3 단계와 4 단계는 실제로 더 긴 변형 manage.py convert_to_south my_app이지만 프로덕션 데이터베이스 수정과 같은 섬세한 상황에서 추가 제어를 선호합니다.


2
찾은 문제에 대한 수정 사항을 포함하도록 답변을 편집하고 (답을 기반으로 문제를 추측하기 만 함) 수백만 행의 프로덕션 데이터베이스에서 테스트했습니다.
hobs

2
이것은 우리가하는 일과 거의 같습니다. 4 단계에서 --delete-ghost-migrations 옵션을 사용하면 1 단계를 생략 할 수 있습니다.
tobych

./manage.py migrate --fake마이그레이션 보류중인 다른 앱을 가짜 마이그레이션하지 않으려면 앱 이름을 명시 적으로 지정해야합니다 .
wadim

2
@wadim 따라서 0 단계 : "디스크의 마이그레이션과 데이터베이스에서 실행 된 마이그레이션 사이에 비동기가 없는지 확인하십시오."
thnee

@thnee 맞습니다. 0 단계에서 설치된 모든 앱을 참조한다고 언급 할 가치가 있습니다. 0 단계를 쉽게 수행 할 수있는 방법을 알고 있습니까?
wadim

7

thnee (그녀의 답변 참조)와 마찬가지로, 우리는 여기 다른 곳에서 인용 한 남쪽 저자의 (Andrew Godwin) 제안에 더 부드럽게 접근하고 있으며 배포하는 동안 코드베이스로 수행하는 작업과 데이터베이스에서 수행하는 작업을 분리하고 있습니다. 배포를 반복 할 수 있어야하기 때문에 :

코드에서 우리가하는 일 :

# 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

해당 코드가 배포 된 후 데이터베이스에 수행하는 작업

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

방금 동일한 작업을 수행했지만 --delete_ghoist-migrations를 사용하는 대신 데이터베이스 항목을 수동으로 삭제한다고 생각합니다. 당신의 방법은 조금 더 좋습니다.
wobbily_col

1

개발자 컴퓨터에서 작업하고 있다면 Dominique가 제안한 것과 거의 비슷한 관리 명령을 작성했습니다.

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

남쪽 저자의 제안과 달리, 이것은 남쪽을 사용하는 다른 설치된 앱을 손상시키지 않습니다.


작성자와 달리 기존 마이그레이션 을 유지 하려는 경우 (예 : 앱과 마이그레이션 기록을 재설정하고 실제 마이그레이션을 유지하려는 경우) 다음을 시도해보십시오. goo.gl/0ZnWm
mgalgs

1

다음은 모든 앱을 재설정하려는 경우에만 해당됩니다. 작업하기 전에 모든 데이터베이스를 백업하십시오. 또한 초기 파일에 depend_on 이 있으면 메모 하십시오.

한 번 :

(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]

푸시하기 전에 프로젝트 부트 스트랩을 테스트하십시오. 그런 다음 각 로컬 / 원격 시스템에 대해 다음을 적용하십시오.

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

다시 참여하려는 각 앱대해 초기 (3)를 수행하십시오 . 재설정 (6)은 마이그레이션 기록 만 삭제하므로 라이브러리에 해롭지 않습니다. 가짜 마이그레이션 (7)은 설치된 타사 앱의 마이그레이션 기록을 되돌립니다.


0

앱 폴더에서 필요한 파일 삭제

인스턴스 경로

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

위키-내 앱

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.