如何简化Django 1.7中的迁移?

时间:2014-05-20 09:09:55

标签: django-1.7 django-migrations

南方已有类似的问题,但我已经开始使用Django 1.7进行我的项目,并且我没有使用南方。

在开发期间,已经创建了许多迁移,但是软件尚未被删除,并且不存在必须迁移的数据库。因此,我想重置迁移,就好像我当前的模型是原始模型并重新创建所有数据库一样。

建议的方法是什么?

编辑:从Django 1.8开始,有一个名为squashmigrations的新命令,它或多或少地解决了这里描述的问题。

11 个答案:

答案 0 :(得分:137)

我得到了这个。我只想出来,这很好。

  • 首先,清除迁移表:

    ./manage.py migrate --fake <app-name> zero
    
  • 删除app-name/migrations/文件夹或内容。

  • 进行迁移:

    ./manage.py makemigrations <app-name>
    
  • 最后整理您的迁移而不进行其他数据库更改:

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

答案 1 :(得分:36)

在Django 1.7版本的迁移过程中,曾经在南方的重置功能已经被取消,转而采用新的功能来压缩&#39;你的迁移。这应该是控制迁移次数的好方法。

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

如果您仍然想从头开始,我假设您仍然可以通过清空迁移表并删除之后再次运行makemigrations的迁移。

答案 2 :(得分: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

答案 3 :(得分: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()

如果您有精心设计的项目,手动删除可能会很累人。这为我节省了很多时间。删除迁移文件是安全的。我已经做了这么多次,没有遇到任何问题......但是。

但是,当我删除迁移文件夹时,makemigrationsmigrate没有为我创建该文件夹。该脚本确保其__init__.py的迁移文件夹保持不变,只删除迁移文件。

答案 4 :(得分:6)

  1. 删除文件: delete_migrations.py(在prj的根目录中):
  2. 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

    4. 或者,您可以从此全部

      编写迁移

答案 5 :(得分:4)

我尝试不同的命令,一些答案对我有所帮助。在我的案例中,只有这个序列修复了MYAPP迁移中的破坏依赖关系,并从头开始清理所有过去的迁移。

在此之前确保数据库已经同步(例如,不要在此处添加新的模型字段或更改元选项)。

void q2_reverseTheArray(char word[100]){
int lentgh=sizeof(word);
int j;
for(j=length+1; j>=0; j--){
    printf("%c", word[j]);
}

其中0002是最后一个makemigrations命令返回的迁移号。

现在您可以正常运行makemigrations / migrate,因为迁移0002已存储但未反映在已同步的数据库中。

答案 6 :(得分:3)

如果您不关心以前的迁移,那么只迁移迁移/目录中的所有迁移呢?您将从头开始迁移序列,将您当前的模型作为参考,就好像您现在已经编写了整个模型一样。

如果你不相信我应该删除,那么请尝试将它们移走。

答案 7 :(得分:1)

一种简单的方法是

转到每个应用并删除迁移文件。

然后转到数据库中的django-migrtaions表并截断它(删除所有条目)。

之后,您可以再次创建迁移。

答案 8 :(得分:0)

cd到src目录 cd /path/to/src

删除迁移目录 rm -rf your_app/migrations/

请注意,这应该分别针对每个应用进行

迁移 python3.3 manage.py migrate

如果你想重新开始 python3.3 manage.py makemigrations your_app

答案 9 :(得分: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中。

答案 10 :(得分:0)

删除我的应用程序中的每个“迁移”文件夹(手动)后,我运行了:

./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并重新开始营业。