Как упростить миграцию в Django 1.7?


есть уже подобные вопросы для юга, но я начал свой проект с Django 1.7 и не использую Юг.

во время разработки было создано много миграций, однако программное обеспечение еще не доставлено, и не существует базы данных, которую необходимо перенести. Поэтому я хотел бы сбросить миграции, как если бы моя текущая модель была оригинальной и воссоздать все базы данных.

каков рекомендуемый способ сделать это?

изменить: С Django 1.8 появилась новая команда с именем squashmigrations что более или менее решает проблему, описанную здесь.

11 89

11 ответов:

в версии миграции Django 1.7 функциональность сброса, которая раньше была на юге, была отброшена в пользу новой функциональности для "раздавливания" ваших миграций. Предполагается, что это хороший способ контролировать количество миграций.

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

Если вы все еще хотите начать с нуля, я предполагаю, что вы все еще можете очистить таблицу миграции и удаление миграций, после которых вы будете запускать makemigrations снова.

Я понял. Я просто понял это, и это хорошо.

  • во-первых, чтобы очистить таблицу миграций:

    ./manage.py migrate --fake <app-name> zero
    
  • удалить app-name/migrations/ папку или содержимое.

  • сделать переносы:

    ./manage.py makemigrations <app-name>
    
  • наконец уберите свои миграции без внесения других изменений в базу данных:

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

у меня просто была такая же проблема. Вот мой обходной путь.

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

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

ручное удаление может быть утомительным, если у вас есть сложный проект. Это сэкономило мне много времени. Удаление файлов миграции безопасно. Я делал это уже в сотый раз, не сталкиваясь с какими-либо проблемами...еще.

однако, когда я удалил папку миграции,makemigrations или migrate не создавал папку обратно на меня. Скрипт гарантирует, что папка миграции со своим __init__.py остается на месте, только удалив перенос файлов.

  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 сделать эмиграцию

  3. ./manage.py migrate --fake

или, вы можете написать миграцию из этого все

Я пробую разные команды, и некоторые ответы помогают мне. Только эта последовательность в моем случае исправила обе сломанные зависимости в миграциях в MYAPP и очистила все прошлые миграции, начиная с нуля.

перед этим убедитесь, что база данных уже синхронизирована (например, не добавляйте здесь новое поле модели или не меняйте параметры Meta).

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

где 0002-номер миграции, возвращенный последней командой makemigrations.

теперь вы можете запустить makemigrations / migrate снова нормально, потому что миграция 0002 хранится, но не отражается в уже синхронизированной базе данных.

Если вы не заботитесь о предыдущих миграциях, как насчет просто удаления всех миграций в каталоге migrations/? вы начнете последовательность миграции с нуля, взяв свою текущую модель в качестве ссылки, как если бы вы написали всю модель сейчас.

Если вы не доверяете мне достаточно, чтобы удалить, а затем попытаться переместить их вместо этого.

самый простой способ-это

перейдите в каждое приложение и удалите файлы миграции.

затем перейдите в таблицу django-migrtaions в базе данных и усеките ее(удалите все записи).

после этого вы можете создать еще раз миграций.

cd в каталог src cd /path/to/src

удалить каталоги миграции rm -rf your_app/migrations/

обратите внимание, что это должно быть сделано для каждого приложения отдельно

миграция python3.3 manage.py migrate

если вы хотите начать все сначала python3.3 manage.py makemigrations your_app

если вы находитесь в режиме разработки, и вы просто хотите сбросить все (базы данных, миграции и т. д.), Я использую этот скрипт, основанный на ответе Абдельхамида Ба. Это позволит стереть таблицы базы данных (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"

сброс-дБ.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.

после удаления каждой папки "миграции" в моем приложении (вручную), я побежал:

./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 и вернулся в бизнес.