IT story

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

hot-time 2020. 9. 2. 20:45
반응형

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


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

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

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

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


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

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

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

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

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

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

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

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

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


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

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


이것이 프로젝트 구조라고 가정하면

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

Manually deleting can be tiring if you have an elaborate project. This saved me a lot of time. Deleting migration files is safe. I have done this an umpteenth number of times without facing any problems...yet.

However when I deleted the migrations folder, makemigrations or migrate did not create the folder back for me. The script makes sure that the migration folder with its __init__.py stays put, only deleting the migration files.


  1. Delete files: delete_migrations.py (in root of 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

OR, you can write migration from this all


I try different commands and some of the answers help me. Only this sequence in my case fixed both broken dependencies in migrations in MYAPP and clean all past migrations starting from scratch.

Before doing this ensure that database is already synced (e.g. do not add a new Model field here or change Meta options).

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

Where 0002 is the migration number returned by the last makemigrations command.

Now you can run makemigrations / migrate again normally because migration 0002 is stored but not reflected in the already-synced database.


If you don't care about previous migrations, what about just removing all migrations in the migrations/ directory? you will start the migration sequence from scratch, taking your current model as reference as if you had written the whole model now.

If you don't trust me enought to remove, then try to move them away instead.


A simple way is

Go to every app and delete the migration files.

Then go to the django-migrtaions table in the database and truncate it(delete all entries).

After that you can create migrations once again.


cd to src directory cd /path/to/src

delete migration directories rm -rf your_app/migrations/

note that this should be done for each app separately

migrate python3.3 manage.py migrate

if you wish to start again python3.3 manage.py makemigrations your_app


If you're in development mode and you just want to reset everything (database, migrations, etc), I use this script based on Abdelhamid Ba's answer. This will wipe the tables of the database (Postgres), delete all migration files, re-run the migrations and load my initial fixtures:

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

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 file:

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

load_initial_fixtures.sh file:

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

Just be sure to change the paths to corresponds to your app. I personally have these scripts in a folder called project_root/script/local, and django's sources are in project_root/src.


After deleting each "migrations" folder in my app (manually), I ran:

./manage.py dbshell
delete from django_migrations;

Then I thought I could just do ./manage.py makemigrations to regenerate them all. However, no changes were detected. I then tried specifying one app at a time: ./manage.py makemigrations foo, ./manage.py makemigrations bar. However, this resulted in circular dependencies that could not be resolved.

Finally, I ran a single makemigrations command that specified ALL of my apps (in no particular order):

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

This time, it worked - circular dependencies were automatically resolved (it created additional migrations files where necessary).

Then I was able to run ./manage.py migrate --fake and was back in business.

참고URL : https://stackoverflow.com/questions/23755523/how-to-simplify-migrations-in-django-1-7

반응형