如何简化Django 1.7中的迁移?


92

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

在开发过程中,创建了许多迁移,但是尚未发布该软件,并且不存在必须迁移的数据库。因此,我想将迁移重置为好像当前模型是原始模型一样,然后重新创建所有数据库。

建议这样做的方法是什么?

编辑:自Django 1.8起,有一个名为squashmigrations的新命令或多或少解决了此处描述的问题。


重置迁移是什么意思?取消吗?
西罗桑蒂利郝海东冠状病六四事件法轮功

Answers:


137

我懂了。我只是想通了,这很好。

  • 首先,要清除迁移表:

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

  • 进行迁移:

    ./manage.py makemigrations <app-name>
  • 最后,整理一下迁移,而无需进行其他数据库更改:

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

5
这是一个很好的答案。仅仅删除迁移并不会撤消任何错误迁移所造成的损害。实际上,这可以清理石板,让您重新开始。
rogueleaderr 2014年

15
如果您要详细说明,这应该是公认的答案。
tani-rokk 2015年

8
伟大的一行回答兄弟,我不知道这是怎么做的
bischoffingston

13
这行代码简单地逐个逆转迁移,直到为止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文件?
Kit Fisto 2014年

使用South,您可以删除再次运行makemigrations时将重新创建的migrations文件夹。我认为这个工程的Django 1.7相同
tijs

4
请注意。在Django 1.7中,如果不小心删除迁移文件夹,则如果您的模型是另一个模型的子级,则可能会引发异常raise KeyError("Migration %s dependencies reference nonexistent parent node %r" % (migration, parent))
Algorithmical

特别是在应用程序中进行./manage.py squashmigrations myapp 0004迁移之前,将先压缩所有迁移。这将创建一个压缩的迁移。0004myapp
布莱斯·金塔

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
这会删除数据,而不仅是迁移
滚刀

2
您也应该删除.pyc文件
shalbafzadeh 2016年

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

如果您有详尽的项目,手动删除可能会很累。这节省了我很多时间。删除迁移文件是安全的。我已经完成了无数次此操作,但是还没有遇到任何问题。

但是,当我删除了迁移文件夹,makemigrations或者migrate没有为我创建该文件夹时。该脚本确保迁移文件夹及其__init__.py保留状态,仅删除迁移文件。


您可以删除迁移文件夹,然后使用空的init .py(例如touch migrations/__init__.py)重新创建它们
滚刀2015年

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迁移--fake

或者,您可以从这全部编写迁移


我必须指定要使用的应用程序名称./manage.py makemigrations,如下所示:./manage.py makemigrations orders alerts
Salami

4

我尝试使用不同的命令,某些答案对我有帮助。在我的情况下,只有该序列修复了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命令返回的迁移号。

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


在上述所有解决方案中,只有这对我有效,没有出现故障,也没有删除数据库。
Vivek Jha

3

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

如果您不信任我要删除,请尝试将其移开。


保持旧移民的意义何在?当人们试图从Django 1.6升级到1.8时,我的问题开始了。
杰伊·莫迪2015年

迁移只是您对数据库所做的更改的跟踪记录。当我的迁移链停止工作时,我不止一次接受vokiman的建议。
亚当·斯塔吉尔

1

一个简单的方法是

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

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

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


1
在删除迁移文件时,请确保您不删除初始化文件。
sprksh

这真的帮助了我。我删除了所有迁移,从sqlite DB中删除了表,但是仍然无法进行迁移...但是,一旦恢复了_init_ .py文件(doh),我就可以再次进行迁移并进行巡航。@sprksh =救生员!
twknab

0

cd到src目录 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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.