web-dev-qa-db-ja.com

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

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

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

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

編集:Django 1.8現在、 squashmigrations という名前の新しいコマンドがあります。これにより、ここで説明する問題が多少なりとも解決されます。

91
Kit Fisto

私はこれを得た。私はこれを理解したばかりで、それは良いことです。

  • まず、移行テーブルをクリアするには:

    ./manage.py migrate --fake <app-name> zero
    
  • app-name/migrations/フォルダーまたはコンテンツを削除します。

  • 移行を行います。

    ./manage.py makemigrations <app-name>
    
  • 最後に、他のデータベースを変更せずに移行を整理します。

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

Django 1.7バージョンの移行では、以前は南にあったリ​​セット機能が削除され、移行を「押しつぶす」ための新しい機能が採用されました。これは、移行の数をチェックするための良い方法であると思われます。

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

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

36
tijs

私はちょうど同じ問題を抱えていました。これが私の回避策です。

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

22

これがプロジェクト構造であると仮定すると、

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を含む移行フォルダーが確実に置かれ、移行ファイルのみが削除されるようにします。

7
user4013889
  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

または、このすべてから移行を書くことができます

6
Ibrohim Ermatov

さまざまなコマンドを試してみると、いくつかの答えが役立ちます。私の場合、このシーケンスのみが、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を通常どおり実行できます。

4
chirale

以前の移行を気にしない場合、migrations /ディレクトリ内のすべての移行を削除するだけではどうですか?モデル全体を作成したかのように、現在のモデルを参照として、移行シーケンスを最初から開始します。

削除するほど私を信頼していない場合は、代わりにそれらを移動してみてください。

3
vokimon

簡単な方法は

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

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

その後、もう一度移行を作成できます。

1
sprksh

開発モードで、すべて(データベース、移行など)をリセットする場合は、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
mrmuggles

アプリの(移行)フォルダーを(手動で)削除した後、次を実行しました。

./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を実行でき、仕事に戻りました。

0
shacker

srcディレクトリへのcd cd /path/to/src

移行ディレクトリを削除するrm -rf your_app/migrations/

これはアプリごとに個別に行う必要があることに注意してください

python3.3 manage.py migrateを移行します

再度開始したい場合はpython3.3 manage.py makemigrations your_app

0
Rubber Duck