Как упростить миграцию в Django 1.7?
есть уже подобные вопросы для юга, но я начал свой проект с Django 1.7 и не использую Юг.
во время разработки было создано много миграций, однако программное обеспечение еще не доставлено, и не существует базы данных, которую необходимо перенести. Поэтому я хотел бы сбросить миграции, как если бы моя текущая модель была оригинальной и воссоздать все базы данных.
каков рекомендуемый способ сделать это?
изменить: С Django 1.8 появилась новая команда с именем squashmigrations что более или менее решает проблему, описанную здесь.
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
остается на месте, только удалив перенос файлов.
- удалить файлы: 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))
DELETE FROM django_migrations Where app in ('app1', 'app2');
./manage.py сделать эмиграцию
./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
и вернулся в бизнес.