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バージョンの移行では、以前は南にあったリセット機能が削除され、移行を「押しつぶす」ための新しい機能が採用されました。これは、移行の数をチェックするための良い方法であると思われます。
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"
これがプロジェクト構造であると仮定すると、
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
を含む移行フォルダーが確実に置かれ、移行ファイルのみが削除されるようにします。
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 makemigrations
./manage.py migrate --fake
または、このすべてから移行を書くことができます
さまざまなコマンドを試してみると、いくつかの答えが役立ちます。私の場合、このシーケンスのみが、MYAPPでの移行での破損した依存関係と、ゼロから開始する過去のすべての移行の両方を修正しました。
これを行う前に、データベースが既に同期されていることを確認してください(たとえば、ここに新しいModelフィールドを追加したり、Metaオプションを変更したりしないでください)。
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を通常どおり実行できます。
以前の移行を気にしない場合、migrations /ディレクトリ内のすべての移行を削除するだけではどうですか?モデル全体を作成したかのように、現在のモデルを参照として、移行シーケンスを最初から開始します。
削除するほど私を信頼していない場合は、代わりにそれらを移動してみてください。
簡単な方法は
すべてのアプリに移動し、移行ファイルを削除します。
次に、データベースのDjango-migrtaionsテーブルに移動し、切り捨てます(すべてのエントリを削除します)。
その後、もう一度移行を作成できます。
開発モードで、すべて(データベース、移行など)をリセットする場合は、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にあります。
アプリの(移行)フォルダーを(手動で)削除した後、次を実行しました。
./manage.py dbshell
delete from Django_migrations;
それから、それらをすべて再生成するために./manage.py makemigrations
を行うことができると思いました。ただし、変更は検出されませんでした。その後、一度に1つのアプリを指定してみました:./manage.py makemigrations foo
、./manage.py makemigrations bar
。ただし、これにより、解決できない循環依存関係が発生しました。
最後に、すべてのアプリを(特定の順序で)指定するmakemigrationsコマンドを1つ実行しました。
./manage.py makemigrations foo bar bike orange banana etc
今回は機能しました-循環依存関係は自動的に解決されました(必要に応じて追加の移行ファイルを作成しました)。
その後、./manage.py migrate --fake
を実行でき、仕事に戻りました。
srcディレクトリへのcd cd /path/to/src
移行ディレクトリを削除するrm -rf your_app/migrations/
これはアプリごとに個別に行う必要があることに注意してください
python3.3 manage.py migrate
を移行します
再度開始したい場合はpython3.3 manage.py makemigrations your_app