如何在 Django 1.7中重置迁移

(我知道有一个标题与此相同,但问题是不同的)。

我已经设法使我的开发机器迁移和生产迁移不同步。

我有一个 Django 的应用程序,使用南。我有自己的工作流程,工作得很好(这可能不是正确的做事方式,但我没有问题)。

基本上,我有一个脚本,可以将生产数据库转储复制到我的开发机器上。它还复制了迁移文件。这样两者就同步了,我就可以像往常一样运行南方司令部了。

现在我已经升级到1.7,并开始使用迁移。当我使用以前的工作流(从生产环境中复制数据库转储和迁移文件)时,它不检测开发机器上的更改。

我已经阅读了迁移文档,我发现正确的使用方法是

  1. 在我的开发机器上运行“制作迁移”和“迁移”。
  2. 在我的开发机器上运行“迁移”来实际进行数据库更改
  3. 复制更改,包括迁移文件。
  4. 在生产机器上运行“ shift”

不管怎样。现在一团糟。我想“重置”我的迁移,从头开始,从现在起正确地做事情。

我需要做什么?

  1. 删除迁移表的内容(在两台机器上) ?
  2. 删除迁移文件夹的内容? (包括 Init.py 文件)。
  3. 根据新文档启动迁移。

我错过什么了吗? 为什么从生产环境(数据库和迁移文件)复制所有内容之后不能检测到我的开发机器上的任何更改

149530 次浏览

快跑

python manage.py migrate your_app zero

这将删除您的 _ app 中的所有表

如果你想,因为你说你想重新开始,你可以删除你的迁移文件夹,或者重命名文件夹,创建一个新的迁移文件夹并运行

python manage.py makemigrations your_app
python manage.py migrate your_app

就像南方一样,你可以来回走..。

# Go to the first migration
python manage.py migrate your_app 0001


# Go to the third migration
python manage.py migrate your_app 0003

所以想象你的第四次迁移是一团糟... 你总是可以迁移到第三次,删除第四次迁移文件,然后再做一次。

注:

这就是为什么你的模型应该在不同的应用程序。假设你有两个模型: 用户和笔记。这是一个很好的实践,创建两个应用程序: 用户和笔记,使迁移是相互独立的。

尽量不要对所有模型使用单个应用程序

我只需在两个环境中执行以下操作(只要代码相同)

  1. 删除迁移文件夹
  2. DELETE FROM django _ miations WHERE app = <your app name>。您也可以直接截断这个表。
  3. python manage.py makemigrations
  4. python manage.py migrate --fake

在此之后,所有的更改都应该能够跨环境检测到。

对于严厉的回答,有一个小小的变化:

$ manage.py migrate --fake <appname> zero
$ rm -rf migrations
$ manage.py makemigrations <appname>
$ manage.py migrate --fake <appname>

这会..。

  • 假装回滚所有的迁移,而不触摸应用程序中的实际表
  • 删除应用程序的现有迁移脚本
  • 为应用程序创建一个新的初始迁移
  • 为应用程序伪造一次迁移到初始迁移

所以这个解决方案今天对我很有效。

  1. 删除名为“ django _ mobilations”的 django 迁移表 (不需要删除整个数据库——只需要删除迁移表。)

  2. 从所有应用程序中删除所有迁移文件(例如0002 _ auto.py 等) ,保留 __init__.py文件。你可以用 Ahmed Bouchefra 的代码:

    - path“ /迁徙/.py”-not-name“ Init.py”-delete

    - path“ /迁徙/.pyc”-delete

(此查找和删除代码仅适用于 linux。对于 Windows,必须手动删除文件。)

  1. 现在运行以下命令:

    python manage.py makemigrations
    
    
    python manage.py migrate --fake
    

Django 将创建一个新的迁移表,并在不触及现有数据的情况下伪造初始迁移到表中。好好享受吧。

我有一个类似的问题,但是当使用 python manage.py showmigrations测试一些相同的解决方案时,我注意到我得到了相同的错误。

最终我找到了这个 邮寄,它帮助我认识到我是过于复杂的事情,本质上有两个用户模型定义。

要重置 所有迁移并从头开始,可以运行以下命令:

1. 重置所有迁移

python manage.py migrate <app_name> zero

如果这导致你的问题,你可以添加 --fake标志到命令的结尾。

2. 创建迁移

python manage.py makemigrations <app_name>

我只做这一步,如果你删除或更改迁移文件

3. 迁移

python manage.py migrate <app_name>

Something 如果您将 --fake命令添加到步骤 # 1,那么您将需要将 --fake-initial添加到迁移命令中,以便使用 python manage.py migrate <app_name> --fake-initial

这对我有用

第一步:
删除所有应用程序 < br >

中的所有“迁移”文件夹

第二步:
创造一个全新的应用程序。
python manage.py justTestApp.
将新应用程序的新“迁移”文件夹复制到所有应用程序 < br >

第三步:
删除“ db.sqlite3”文件。
删除“ just TestApp”文件夹 < br >

第四步:
python manage.py makemigrations
python manage.py migrate

在项目中重置了不需要的迁移之后,仍然会出现在测试数据库(由 pytest 创建的数据库)中存在不需要的迁移的问题。

您可以通过将 --create-db添加到您的 test 命令中来重置 测试数据库:

py.test path/to-tests.py --create-db

正如@brunofitas 提到的,回到上一次迁移对我的情况有所帮助。然后我删除了从那一点到最后一点的迁移,运行 makemigrationsmigrated,然后我就完成了。

如果你想要一个完全干净的开始,你最好把尸体放下。这意味着要重新创建它、添加特权、重新生成所有迁移、重新运行它们并创建一个超级用户。

好消息是,您可以很容易地将所有这些命令转换为一个或几个行命令。

新的迁移文件

如果你删除整个文件夹,你将不得不运行 makemigrations命令提到所有的应用程序名称。如果你经常这么做,那就麻烦了。要让 Django 看到需要迁移的应用程序,你需要把 migrations文件夹和 __init__.py放在里面。

下面是一个 bash 命令:

find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf

然后是通常的(这应该会为 所有创建以前有过迁移的应用程序的迁移) :

python manage.py makemigrations

重置数据库

对于 SQLite,只需删除数据库文件。

对于 PostgreSQL,在控制台中运行以下命令:

psql -c "drop database <db_name>;"
psql -c "create database <db_name>;"
psql -c "grant all on database <db_name> to <db_user>;"

最后使用

python manage.py migrate

超级用户

你们肯定会错过一个超级用户所以你们最好还是:

python manage.py createsuperuser

无输入的方法是将 python 代码导入 shell:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'badmin@myproject.com', 'pa$$w0rd')" | python manage.py shell

一般来说,这些非常常见的行为 -帮自己一个忙,写一点抨击。多年来,我不仅和姜戈一起工作,还为我节省了许多积累的时间。因为拥有一个完整的实用程序文件来存储更多这些方便的函数比单线命令更好。然后你可以这样运行:

django --reset_migrations
db --reset <my_db>
django --migrate

或者,如果你发现自己重复同样的几个动作,甚至可以把它们聚合成一行。把这个添加到您的 bashprofile 中

reset_django() {
find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf
python manage.py makemigrations
psql -c "drop database <db_name>;"
psql -c "create database <db_name>;"
psql -c "grant all on database <db_name> to <db_user>;"
python manage.py migrate
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'badmin@myproject.com', 'pa$$w0rd')" | python manage.py shell
}

我的 Django 小工具给我灵感:

#!/bin/bash




django() {


project_name=$(basename $PWD)
project_path="$PWD"
manage_path="${project_path}/${project_name}/manage.py"


if [ ! -f $manage_path ] ; then  # No project/manage.py
echo "Error: Could not locate Django manage.py file."
return -1
fi


if [ $# -eq 0 ] ; then
echo "Django project detected."
fi


while [ ! $# -eq 0 ]
do
case "$1" in


--help | -h)
echo "Django shortcut, unknown commands are forwarded to manage.py"
echo "  -c, --check         Run Django manage.py check."
echo "  --req           Install requirements."
echo "  -r, --run           Run server."
echo "  -s, --shell         Run Django shell plus."
echo "  -sd, --shell            Run Django shell plus. Debug DB (print sql)"
echo ""
;;


--check | -c)
python $manage_path check
;;


--shell | -s)
python $manage_path shell_plus --bpython
;;


--shell | -sd)
python $manage_path shell_plus --bpython --print-sql
;;


--run | -r)
python $manage_path runserver
;;


--req)
pip install -r $project_path/requirements.txt
;;


--mig | -m)
python $manage_path makemigrations
python $manage_path migrate
;;


--reset_migrations)
find . -path "*migrations*" -not -regex ".*__init__.py" -a -not -regex ".*migrations" | xargs rm -rf
python $manage_path makemigrations
;;


*)
python $manage_path "$@"
;;


esac
shift
done


}

面对类似的问题,这对我很有效。

python manage.py migrate <app_name> zero --fake


python manage.py migrate <app_name>