Django 1.7에서 마이그레이션을 단순화하는 방법은 무엇입니까?


92

South에 대한 비슷한 질문이 이미 있지만 Django 1.7로 프로젝트를 시작했으며 South를 사용하지 않습니다.

개발 중에 많은 마이그레이션이 생성되었지만 소프트웨어는 아직 제공되지 않았으며 마이그레이션해야하는 데이터베이스도 없습니다. 따라서 현재 모델이 원래 모델 인 것처럼 마이그레이션을 재설정하고 모든 데이터베이스를 다시 만들고 싶습니다.

권장하는 방법은 무엇입니까?

편집 : Django 1.8 부터 여기에 설명 된 문제를 다소 해결하는 squashmigrations 라는 새로운 명령이 있습니다.


마이그레이션을 재설정한다는 것은 무엇을 의미합니까? 취소 하시겠습니까?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

답변:


137

알 겠어. 나는 이것을 알아 냈고 그것은 좋다.

  • 먼저 마이그레이션 테이블을 지우려면 :

    ./manage.py migrate --fake <app-name> zero
  • app-name/migrations/폴더 또는 내용을 제거하십시오 .

  • 마이그레이션을 수행하십시오.

    ./manage.py makemigrations <app-name>
  • 마지막으로 다른 데이터베이스 변경없이 마이그레이션을 정리하십시오.

    ./manage.py migrate --fake <app-name>

5
이것은 좋은 대답입니다. 마이그레이션을 삭제하는 것만으로 마이그레이션에 결함이있는 피해는 취소되지 않습니다. 이것은 실제로 슬레이트를 청소하고 다시 시작할 수있게합니다.
rogueleaderr 2008

15
조금 더 자세히 설명해 주시면 이것이 허용되는 대답입니다.
tani-rokk 2015-04-22

8
위대한 하나의 라인 응답 형제, 나는 이것이 무엇을 아무 생각이 없다
bischoffingston

13
이 줄은까지 마이그레이션을 하나씩 반전합니다 zero. 장고 마이그레이션 시스템의 경우, <app-name> 이제 새로운 응용 프로그램입니다 및 makemigrations <app-name>부터 시작됩니다 0001. --fake테이블이 실제로 수정되는 것을 방지하며 마이그레이션은 반전 된 것으로 표시되어야하며 실제로 스키마에 적용되지 않아야합니다. (탄 - rokk, @Fabrizio @ 완전성을 위해 작은 explainations 추가)
미르 나짐

17
manage.py migrate --fake <app-name> zero마이그레이션 테이블을 지우려면 <app-name> / migrations / 폴더 또는 내용을 제거하십시오. 그런 다음 manage.py makemigrations <app-name>마지막으로 manage.py migrate --fake <app-name>합니다. 이렇게하면 다른 데이터베이스 변경없이 마이그레이션을 정리할 수 있습니다.
doeke

36

Django 1.7 버전의 마이그레이션에서는 마이그레이션을 '스 쿼싱'하는 새로운 기능을 위해 South에 있던 재설정 기능이 삭제되었습니다. 이것은 마이그레이션 수를 확인하는 좋은 방법입니다.

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

여전히 처음부터 실제로 시작하려면 마이그레이션 테이블을 비우고 마이그레이션을 제거한 후 makemigrations다시 실행할 수 있다고 가정 합니다.


2
마이그레이션 테이블을 비우는 것 외에 어떻게 "마이그레이션을 제거"합니까? 전체 폴더를 제거합니까 아니면 00X _ *. py 파일 만 제거합니까?
Kit Fisto 2014 년

South를 사용하면 makemigrations를 다시 실행할 때 다시 생성되는 마이그레이션 폴더를 제거 할 수 있습니다. 나는 이것이 Django 1.7에서 동일하게 작동한다고 가정합니다
tijs

4
메모입니다. Django 1.7에서 신중하게 마이그레이션 폴더를 삭제하면 모델이 다른 모델의 자식 인 경우 예외가 발생할 수 있습니다raise KeyError("Migration %s dependencies reference nonexistent parent node %r" % (migration, parent))
Algorithmatic

특히 응용 프로그램에서 ./manage.py squashmigrations myapp 0004마이그레이션하기 전에 모든 마이그레이션을 스쿼시합니다 . 이렇게하면 단일 스쿼시 마이그레이션이 생성됩니다. 0004myapp
Bryce Guinta 2016

22

나는 단지 같은 문제가 있었다. 내 해결 방법은 다음과 같습니다.

#!/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


13
이 데이터뿐 아니라 마이그레이션 삭제
호브

2
당신도 파일을 .pyc 파일 삭제해야
shalbafzadeh

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

정교한 프로젝트가있는 경우 수동으로 삭제하면 지칠 수 있습니다. 이것은 저에게 많은 시간을 절약했습니다. 마이그레이션 파일을 삭제하는 것은 안전합니다. 나는 아무 문제없이 이것을 여러 번 수행했지만 ...

그러나 마이그레이션 폴더를 삭제 makemigrations하거나 migrate폴더를 다시 만들지 않았습니다. 스크립트는 __init__.py마이그레이션 파일 만 삭제하고 마이그레이션 폴더가 그대로 유지되도록합니다.


방금 마이그레이션 폴더를 삭제하고 빈 그들을 다시 수 초기화 평 (예 touch migrations/__init__.py)
호브

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))
  1. DELETE FROM django_migrations Where app in ('app1', 'app2');

  2. ./manage.py makemigrations

  3. ./manage.py migrate --fake

또는이 모든 것에서 마이그레이션을 작성할 수 있습니다.


나는을위한 응용 프로그램 이름을 지정했습니다 ./manage.py makemigrations대한 작업과 같이 :./manage.py makemigrations orders alerts
살라미

4

다른 명령을 시도하고 일부 답변이 도움이됩니다. 내 경우에만이 시퀀스만이 MYAPP의 마이그레이션에서 끊어진 종속성을 수정하고 처음부터 모든 이전 마이그레이션을 정리했습니다.

이를 수행하기 전에 데이터베이스가 이미 동기화되었는지 확인하십시오 (예 : 여기에 새 모델 필드를 추가하거나 메타 옵션을 변경하지 마십시오).

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

여기서 0002는 마지막 makemigrations 명령에서 반환 된 마이그레이션 번호입니다.

이제 마이그레이션 0002가 저장되지만 이미 동기화 된 데이터베이스에 반영되지 않으므로 makemigrations / migrate를 정상적으로 다시 실행할 수 있습니다.


위에서 언급 한 모든 솔루션 중에서 이것은 결함없이 데이터베이스를 삭제하지 않고 저에게 효과적이었습니다.
Vivek Jha

3

이전 마이그레이션에 관심이 없다면 migrations / 디렉토리에서 모든 마이그레이션을 제거하는 것은 어떻습니까? 마치 지금 전체 모델을 작성한 것처럼 현재 모델을 참조로 사용하여 처음부터 마이그레이션 시퀀스를 시작합니다.

제거 할 수있을만큼 나를 믿지 않는다면, 대신 이동 시키십시오.


이전 마이그레이션을 유지하는 것의 중요성은 무엇입니까? 내 질문은 django 1.6에서 1.8로 업그레이드하려고 할 때 발생합니다.
Jay Modi

마이그레이션은 단순히 데이터베이스에 대한 변경 사항의 추적 기록입니다. 마이그레이션 체인이 작동을 멈출 때 vokiman의 조언을 두 번 이상 받았습니다.
Adam Starrh

1

간단한 방법은

모든 앱으로 이동하여 마이그레이션 파일을 삭제하십시오.

그런 다음 데이터베이스의 django-migrtaions 테이블로 이동하여 잘라냅니다 (모든 항목 삭제).

그런 다음 다시 마이그레이션을 만들 수 있습니다.


1
마이그레이션 파일을 삭제하는 동안 init 파일을 삭제하지 마십시오 .
sprksh 2011 년

이것은 정말 나를 도왔습니다. 나는 일단 나는, 그러나 ... 모든 마이그레이션을 삭제 내 SQLite는 DB에서 테이블을 감소하지만, 여전히 makemigrations 할 수 없습니다 복원 _init_ 평 파일 내가 다시 makemigrations 수 있었고 순항 수 (DOH)를. @sprksh = 생명의 은인!
twknab

0

src 디렉토리로 cd cd /path/to/src

마이그레이션 디렉토리 삭제 rm -rf your_app/migrations/

이 작업은 각 앱에 대해 개별적으로 수행해야합니다.

마이그레이션 python3.3 manage.py migrate

다시 시작하려면 python3.3 manage.py makemigrations your_app


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"

reset-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 $$;

migration.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에 있습니다.


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있었고 다시 사업을 시작했습니다.

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