(我知道有一个与此相同的标题,但问题不同)。
我设法让我的开发机器迁移和生产迁移不同步。
我有一个使用 South 的 Django 应用程序。我有自己的工作流程,运行良好(这可能不是正确的做事方式,但我没有遇到任何问题)。
基本上我有一个将生产数据库转储复制到我的开发机器的脚本。它还复制了迁移文件。这样两者就同步了,我可以正常运行 South 命令。
现在我已经升级到 1.7,并开始使用迁移。当我使用我以前的工作流程(复制数据库转储和从生产中迁移文件)时,它没有检测到我的开发机器上的更改。
我已经阅读了迁移文档,我发现使用它的正确方法是
在我的开发机器上运行“make migrations”和“migrate”。在我的 devlopemnt 机器上运行“迁移”以实际进行数据库更改复制更改,包括迁移文件。在生产机器上运行“迁移”。 (没有“makemigrations”步骤)
反正。现在一切都是一团糟。我想“重置”我的迁移并从头开始,从现在开始正确地做事。
我需要做什么?
删除迁移表的内容(在两台机器上)?删除迁移文件夹的内容? (包括 init.py 文件)。根据新文档的文档开始迁移。
我错过了什么吗?是否有理由从生产中复制所有内容(数据库和迁移文件)之后在我的开发机器上检测不到任何更改
我会在两种环境中执行以下操作(只要代码相同)
删除您的迁移文件夹 DELETE FROM django_migrations WHERE app =
在此之后,您的所有更改都应该跨环境检测到。
跑
python manage.py migrate your_app zero
这将从 your_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
所以想象一下你的第 4 次迁移是一团糟……你总是可以迁移到第 3 次,删除第 4 次迁移文件,然后再做一次。
笔记:
这是您的模型应该在不同应用程序中的原因之一。假设您有 2 个模型:用户和注释。创建 2 个应用程序是一个很好的做法:用户和注释,因此迁移彼此独立。
尽量不要为所有模型使用单个应用程序
对沙希尔的回答略有不同:
$ manage.py migrate --fake <appname> zero
$ rm -rf migrations
$ manage.py makemigrations <appname>
$ manage.py migrate --fake <appname>
这将 ...
假装回滚所有迁移而不触及应用程序中的实际表
删除应用程序的现有迁移脚本
为应用创建新的初始迁移
伪造迁移到应用程序的初始迁移
zero
放在 --fake
之前吗?这就是它对我有用的方式。
-h
所说的格式:Usage: ./manage.py migrate [options] [app_label] [migration_name]
要重置所有迁移并重新开始,您可以运行以下命令:
1.重置所有迁移
python manage.py migrate <app_name> zero
ℹ️ 如果这导致您出现问题,您可以将 --fake 标志添加到命令的末尾。
2. 创建迁移
python manage.py makemigrations <app_name>
ℹ️ 仅当您删除或更改迁移文件时才执行此步骤
3. 迁移
python manage.py migrate <app_name>
⚠️ 如果您在步骤 1 中添加了 --fake 命令,则需要将 --fake-initial 添加到 migrate 命令中,以便 python manage.py migrate
我遇到了类似的问题,但是在使用 python manage.py showmigrations
测试其中一些相同的解决方案时,我注意到我遇到了同样的错误。
最终,我发现了这个 post,它帮助我意识到我的事情过于复杂,并且基本上定义了两个用户模型。
所以这个解决方案今天对我有用。
删除名为“django_migrations”的 django 迁移表(无需删除整个数据库 - 只需删除迁移表。)从所有应用程序中删除所有迁移文件(例如 0002_auto.py 等),保留 __init__.py 文件。您可以使用来自 Ahmed Bouchefra 的代码:find 。 -path "/migrations/.py" -not -name "init.py" -delete find 。 -path "/migrations/.pyc" -delete
(此查找和删除代码仅适用于 linux。对于 Windows,您必须手动删除文件。)
现在运行以下命令: python manage.py makemigrations python manage.py migrate --fake
django 将创建一个新的迁移表,并在不触及现有数据的情况下将初始迁移伪造到表中。享受。
这对我有用
Step1:删除所有应用程序中的所有“迁移”文件夹
Step2:
创建一个全新的应用程序。
python manage.py justTestApp
.
将新应用的新“迁移”文件夹复制到所有应用
Step3:删除“db.sqlite3”文件。删除“justTestApp”文件夹
第四步:
python manage.py makemigrations
python manage.py migrate
在您在项目中重置不需要的迁移后,您仍然会遇到在测试数据库(由 pytest 创建的数据库)中存在这些不需要的迁移的问题。
您可以通过将 --create-db
添加到您的测试命令来重置 测试数据库:
py.test path/to-tests.py --create-db
正如@brunofitas 所提到的,回到之前的迁移对我的情况有所帮助。此后,我删除了从该点到最后一个的迁移,运行 makemigrations
、migrated
并完成了。
如果你想要一个完全干净的开始,你会想要放弃数据库。这意味着然后重新创建它,添加权限,重新生成所有迁移,重新运行它们并创建一个超级用户。
好消息是您可以轻松地将所有这些变成单行/几行命令。
新的迁移文件
如果您删除整个文件夹,您将不得不运行 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
一般来说,这些非常常见的操作 - 帮自己一个忙,写一点 bash。多年来,它不仅为我节省了很多很多与 Django 合作的时间。因为比单行命令更好的是拥有一个完整的实用程序文件来存储更多这些方便的功能。然后你可以运行类似的东西:
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 lite 实用程序的灵感:
#!/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
}
makemigrations
指定应用程序。例如,如果您的应用名为polls
,则为python manage.py makemigrations polls
。python manage.py flush --no-input
避免在键入 yes 后不执行任何操作以继续