Django 1.7での移行を簡素化する方法


92

南についても同様の質問がありますが、私はDjango 1.7でプロジェクトを開始し、南を使用していません。

開発中に多くの移行が作成されましたが、ソフトウェアはまだ提供されておらず、移行する必要のあるデータベースはありません。したがって、現在のモデルが元のモデルであるかのように移行をリセットし、すべてのデータベースを再作成したいと思います。

それを行うための推奨される方法は何ですか?

編集: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
これは良い答えです。マイグレーションを削除するだけでは、不完全なマイグレーションが行ったダメージは取り消されません。これでスレートがきれいになり、最初からやり直すことができます。
ローグリーダー14

15
少し詳しく説明するとしたら、これが受け入れられる答えになるはずです。
tani-rokk 2015

8
素晴らしい一行の答えの仲間、私はこれが何をしているのか分かりません
bischoffingston

13
この行は、まで、移行を1つずつ逆にしますzero。Django移行システムの場合、<app-name> は新しいアプリになり、makemigrations <app-name>から開始され0001ます。 --fakeテーブルが実際に変更されるのを防ぎます。移行は逆にマークされるだけで、実際にはスキーマに適用されません。(完全を期すために小さな説明を追加、@ tani-rokk、@ Fabrizio)
Mir Nazim

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バージョンの移行では、以前は南にあったリ​​セット機能が削除され、移行を「押しつぶす」ための新機能が採用されました。これは、マイグレーションの数を抑えるための良い方法と思われます。

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

それでも本当に最初からmakemigrationsやり直したい場合は、移行テーブルを空にして移行を削除した後、再度実行することでできると思います。


2
移行テーブルを空にする以外に、「移行を削除」するにはどうすればよいですか?フォルダー全体または00X _ *。pyファイルのみを削除しますか?
キットフィスト

Southでは、makemigrationsを再度実行すると再作成されるmigrationsフォルダーを削除できます。これはDjango 1.7でも同じように機能すると
思います

4
ただのメモ。Django 1.7では、移行フォルダを慎重に削除しないと、モデルが別の子である場合に例外が発生する可能性がありますraise KeyError("Migration %s dependencies reference nonexistent parent node %r" % (migration, parent))
Algorithmatic

具体的に./manage.py squashmigrations myapp 00040004、アプリケーションでの移行前にすべての移行を押しつぶしますmyapp。これにより、単一の押しつぶされた移行が作成されます。
ブライスギンタ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
これにより、移行だけでなくデータも削除されます
2015年

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

手の込んだプロジェクトがある場合、手動で削除するのは面倒です。これにより多くの時間を節約できました。移行ファイルを削除しても安全です。私はこれを何回も何も問題に直面することなく行った...まだ。

ただし、migrationsフォルダーを削除したとき、makemigrationsまたはmigrateフォルダーを作成し直さなかったとき。このスクリプトにより、移行フォルダーがそのまま__init__.py残り、移行ファイルのみが削除されます。


あなただけの移行フォルダを削除し、空でそれらを再作成することができ初期化の.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、2016

1

簡単な方法は

すべてのアプリに移動し、移行ファイルを削除します。

次に、データベースのdjango-migrtaionsテーブルに移動し、それを切り捨てます(すべてのエントリを削除します)。

その後、もう一度マイグレーションを作成できます。


1
移行ファイルを削除するときは、initファイルを削除しないでください。
sprksh 2016

これは本当に役に立ちました。私は一度しかし、...、すべての移行を削除し、私のsqliteのDBからテーブルを落としたが、それでもmakemigrationsすることができませんでした復元_init_の.pyファイル(DOH)を、私は再びmakemigrationsすることができたとクルージングます。@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

アプリの「migrations」フォルダを(手動で)削除した後、実行しました:

./manage.py dbshell
delete from django_migrations;

それから私は./manage.py makemigrationsそれらすべてを再生するために私ができることができると思った。ただし、変更は検出されませんでした。次に、一度に1つのアプリを指定してみました:./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.