마지막 마이그레이션을 되 돌리는 방법은 무엇입니까?


447

새 테이블을 추가 한 마이그레이션을 만들었으며 새 마이그레이션을 만들지 않고 테이블을 되돌리고 마이그레이션을 삭제하려고합니다.

어떻게합니까? 마지막 마이그레이션을 되 돌리는 명령이 있는데 마이그레이션 파일을 간단히 삭제할 수 있습니까?

답변:


797

이전 마이그레이션으로 마이그레이션하여 되돌릴 수 있습니다.

예를 들어, 마지막 두 마이그레이션이 다음과 같은 경우

  • 0010_previous_migration
  • 0011_migration_to_revert

그렇다면 당신은 할 것입니다 :

./manage.py migrate my_app 0010_previous_migration 

그런 다음 마이그레이션을 삭제할 수 있습니다 0011_migration_to_revert.

Django 1.8 이상을 사용하는 경우 모든 마이그레이션의 이름을

./manage.py showmigrations my_app

앱의 모든 마이그레이션을 취소하려면 다음을 실행하십시오.

./manage.py migrate my_app zero

7
나는이 문제에 대해 오래되고 더 이상 작동하지 않는 많은 답변을 보았습니다. 이것은 Django 1.8에서 작동하기 때문에 +1입니다.
AlanSE

2
앱에 마이그레이션 파일이 하나만있는 경우 / 초기 마이그레이션 초기 마이그레이션을 취소해야합니까?
Adiyat Mubarak

37
migrate명령을 사용 ./manage.py migrate my_app zero하면 앱에 대한 모든 마이그레이션을 적용 취소 할 수 있습니다.
Alasdair

4
어떤 이유로 ./manage.py migrate my_app 0010_previous_migration이 작동하지 않았습니다. 그래서 ./manage.py migrate my_app 0010을 사용해 보았습니다. Django 1.8이 전체 마이그레이션 이름을 사용하지 않는 이유는 무엇입니까?
Varun Verma

4
실제 마이그레이션 이름을 사용하고 있지만를 사용 '0010_previous_migration'하지 않는 한 왜 그 동작을 볼 수 있는지 모르겠습니다.
Alasdair

36

Alasdair의 답변은 기본 사항을 다룹니다.

  • 원하는 마이그레이션을 식별하십시오. ./manage.py showmigrations
  • migrate 앱 이름과 마이그레이션 이름을 사용하여

그러나 모든 마이그레이션 취소 할 수 있는 것은 아닙니다 . Django에 반전을 수행 할 규칙이없는 경우에 발생합니다. 에 의해 자동으로 마이그레이션 된 대부분의 변경 ./manage.py makemigrations에는 취소가 가능합니다. 그러나 사용자 정의 스크립트는 다음 예제에 설명 된대로 정방향 및 역방향으로 작성해야합니다.

https://docs.djangoproject.com/en/1.9/ref/migration-operations/

무 작동 반전을 수행하는 방법

RunPython작업 이있는 경우 논리적으로 엄격한 역전 스크립트를 작성하지 않고 마이그레이션을 취소 할 수 있습니다. 다음 링크에서 문서의 예제에 대한 빠른 해킹을 통해 데이터베이스를 마이그레이션 한 후에도 데이터베이스를 마이그레이션 한 후와 동일한 상태로 유지할 수 있습니다.

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

def forwards_func(apps, schema_editor):
    # We get the model from the versioned app registry;
    # if we directly import it, it'll be the wrong version
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).bulk_create([
        Country(name="USA", code="us"),
        Country(name="France", code="fr"),
    ])

class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.RunPython(forwards_func, lambda apps, schema_editor: None),
    ]

이것은 장고 1.8, 1.9에서 작동합니다.


업데이트 : 이것을 작성하는 더 좋은 방법은 위의 코드 조각 으로 대체 lambda apps, schema_editor: None하는 것 migrations.RunPython.noop입니다. 이것들은 기능적으로 같은 것입니다. (의견에 대한 신용)


5
이후 장고 1.8에서, 당신은 사용해야 RunPython.noop인라인 람다 또는 equivelent 대신 : docs.djangoproject.com/en/1.8/ref/migration-operations/...
SpoonMeiser

@SpoonMeiser이 예제의 구문에서는 다음과 같이 보입니다 migrations.RunPython(forwards_func, migrations.RunPython.noop). 기능적으로 확인해야합니다. 그것은 언젠가 이것에 대한 답변이나 편집으로 추가되어야합니다.
AlanSE

13

위의 솔루션이 실제로 사용 사례를 다루지 않기 때문에 여기에 내 솔루션이 있습니다 RunPython.

ORM을 통해 테이블에 액세스 할 수 있습니다.

from django.db.migrations.recorder import MigrationRecorder

>>> MigrationRecorder.Migration.objects.all()
>>> MigrationRecorder.Migration.objects.latest('id')
Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model>
>>> MigrationRecorder.Migration.objects.latest('id').delete()
Out[4]: (1, {u'migrations.Migration': 1})

따라서 테이블을 쿼리하고 관련된 항목을 삭제할 수 있습니다. 이 방법으로 상세하게 수정할 수 있습니다. RynPython또한 마이그레이션을 통해 추가 / 변경 / 제거 된 데이터를 관리해야합니다. 위의 예는 Djang ORM을 통해 테이블에 액세스하는 방법 만 표시합니다.


ForeignKeys를 사용하여 새 모델을 작성하고 여러 마이그레이션을 수행하면 모두 잘못 인식하고 새 모델이지만 때로는 동일한 모델 이름 또는 동일한 관계 이름으로 2-3 마이그레이션을 다시 시작하면이 솔루션이 분명히 승자입니다. 내가 같은 오류 메시지가 있었다 django.db.utils.ProgrammingError: relation "<relation name>" already exists내가 만든 따라서 migrate --fake내가 돌아 가려고 노력 때문에 잘못 인을, 그럼 내가 가지고 psycopg2.ProgrammingError: relation "<other <relation name>" does not exist감사를
onekiloparsec

10

다른 방법으로는 수동으로 생성 된 테이블을 삭제하는 것입니다.

이와 함께 특정 마이그레이션 파일을 삭제해야합니다. 또한 django-migrations 테이블에서 해당 특정 마이그레이션과 관련된 특정 항목 (아마도 마지막 항목)삭제해야 합니다.


이 경우주의하십시오-db가 적절한 지 확인해야합니다.
Sławomir Lenart 2016 년

4
나는 매우 신중하게 추가 할 것입니다. 제약 조건과 같이 Postgres에서 많은 것들을 망칠 수 있습니다.
joedborg

9

복귀 후까지 마이그레이션 파일을 삭제하지 마십시오. 나는이 실수를했고 마이그레이션 파일없이 데이터베이스는 무엇을 제거 해야하는지 알지 못했습니다.

python manage.py showmigrations
python manage.py migrate {app name from show migrations} {00##_migration file.py}

마이그레이션 파일을 삭제하십시오. 원하는 마이그레이션이 모델에 있으면 ...

python manage.py makemigrations
python manage.py migrate

8

1.9.1 에서이 작업을 수행했습니다 (최근 또는 최신 마이그레이션을 삭제하기 위해).

  1. rm <appname>/migrations/<migration #>*

    예: rm myapp/migrations/0011*

  2. 데이터베이스에 로그인하여이 SQL을 실행했습니다 (이 예에서는 postgres).

    delete from django_migrations where name like '0011%';

그런 다음 방금 삭제 한 마이그레이션 번호 (이 경우 11)로 시작하는 새 마이그레이션을 만들 수있었습니다.


1
+1 이것이 효과가 있지만, 최후의 수단으로이 방법을 저장해야합니다. 또한 문제가있는 마이그레이션이 기여한 열 / 테이블을 편집 / 삭제해야합니다.
nehem

좋은 점-마이그레이션을 만들 때이 옵션을 사용했지만 "./manage.py migrate"를 아직 실행하지 않았습니다.
MIkee

3

이 답변은 Alasdair의 최고 답변이 도움이되지 않는 경우 와 비슷한 경우에 해당됩니다 . (예 : 매번 새로 마이그레이션 할 때마다 원치 않는 마이그레이션이 다시 생성되거나 되돌릴 수없는 더 큰 마이그레이션에 있거나 테이블이 수동으로 제거 된 경우)

... 새 마이그레이션을 만들지 않고 마이그레이션을 삭제 하시겠습니까?

TL; DR : 마지막 되 돌린 (혼란 된) 마이그레이션을 몇 개 삭제하고 모델을 수정 새로 마이그레이션 할 수 있습니다 . 다른 방법사용 하여 migrate 명령 으로 테이블작성하지 않도록 구성 할 수도 있습니다 . 현재 모델과 일치하도록 마지막 마이그레이션을 작성해야합니다 .


케이스 사람이 존재해야 모델에 대한 테이블을 생성하지 않는 이유 :

A) 머신이나 조건이없는 데이터베이스에는 그러한 테이블이 없어야합니다.

  • 언제 : 다른 모델의 모델 상속을 위해서만 만들어진 기본 모델입니다.
  • 솔루션 : 설정class Meta: abstract = True

B) 테이블은 다른 방법으로 또는 특별한 방법으로 수동으로 생성되지 않습니다.

  • 해결책: 사용 class Meta: managed = False
    마이그레이션은 테스트에서만 작성되지만 사용되지는 않습니다. 마이그레이션 파일이 중요합니다. 그렇지 않으면 재현 가능한 초기 상태에서 시작하여 데이터베이스 테스트를 실행할 수 없습니다.

씨) 이 테이블은 일부 기계에서만 사용됩니다 (예 : 개발 중).

  • 해결책: 특수한 조건에서만 INSTALLED_APPS에 추가 된 새 애플리케이션으로 모델을 이동하거나 조건부를 사용하십시오 class Meta: managed = some_switch.

디) 프로젝트는 여러 데이터베이스를 사용합니다.settings.DATABASES

  • 솔루션 : 데이터베이스 라우터 작성allow_migrate 테이블을 작성해야하는 위치와 그렇지 않은 데이터베이스를 구별하기 위해 메소드 를 사용 를 작성하십시오.

마이그레이션은 모든 경우 A), B), C), D)에서 Django 1.9+로 생성되지만 (Django 1.8의 경우 B, C, D의 경우에만) 생성되지만 적절한 경우에만 데이터베이스에 적용되거나 필요합니다. Django 1.8 이후 테스트를 실행하기 위해 마이그레이션이 필요했습니다. Django 1.9+에서 managed = False 모델의 경우에도 관리 / 관리되지 않는 모델간에 ForeignKey를 만들거나 나중에 모델을 관리 = 참으로 만들 수 있도록 관련된 모든 현재 상태가 마이그레이션으로 기록됩니다. (이 질문은 Django 1.8에서 작성되었습니다. 여기에있는 모든 내용은 1.8에서 현재 2.2 사이의 버전에 유효해야합니다.)

마지막 마이그레이션이 쉽게 되돌릴 수없는 경우 (데이터베이스 백업 후) 조심스럽게 되돌릴 수 있습니다. ./manage.py migrate --fake my_app 0010_previous_migration 하고 테이블을 수동으로 삭제할 수 있습니다.

필요한 경우 고정 모델에서 고정 마이그레이션을 작성하고 데이터베이스 구조를 변경하지 않고 적용하십시오 ./manage.py migrate --fake my_app 0011_fixed_migration.


3

마이그레이션을 되 돌리는 동안 문제가 발생하여 엉망이 된 경우 fake마이그레이션 을 수행 할 수 있습니다 .

./manage.py migrate <name> --ignore-ghost-migrations --merge --fake

들어 장고 버전 <1.7 이있는 항목을 만듭니다south_migrationhistory 테이블을 해당 항목을 삭제해야합니다.

이제 마이그레이션을 쉽게 되돌릴 수 있습니다.

추신 : 나는 많은 시간 동안 붙어 있었고 가짜 마이그레이션을 수행 한 다음 되돌아 가면 도움이되었습니다.


1
이 답변은 Django <1.7에 대한 것입니다.
hynekcer 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.