与this question一样,我为我的数据库设置了一个基于dumpdata
的备份系统。该设置类似于运行调用dumpdata
的cron脚本并将备份移动到远程服务器,目的是简单地使用loaddata
来恢复数据库。但是,我not sure this plays well with migrations。 loaddata
现在有一个ignorenonexistent
开关来处理已删除的模型/字段,但它无法解决使用一次性默认值添加列或应用RunPython
代码的情况。
我看到它的方式,有两个子问题需要解决:
dumpdata
输出文件我很难解决如何在不引入大量开销的情况下解决第一个问题。是否足以为每个包含{app_name: migration_number}
映射的备份保存额外的文件?
第一个问题解决后,我认为第二个问题更容易解决,因为这个过程大致是:
loaddata
this question中有一些代码(从错误报告中链接),我认为可以为此目的进行调整。
由于这些是数据库的相当规则/大型快照,因此我不希望将它们作为数据迁移使迁移目录混乱。
答案 0 :(得分:4)
我正在采取以下步骤在项目的任何实例之间备份,恢复或传输postgresql数据库:
我们的想法是尽可能减少迁移,就像在空数据库中第一次运行manage.py makemigrations
一样。
假设我们的开发环境有一个可用的数据库。此数据库是生产数据库的当前副本,不应对任何更改开放。我们添加了模型,更改了属性等,这些操作已经生成了额外的迁移。
现在数据库已准备好迁移到生产环境 - 如前所述 - 不向公众开放,因此不会以任何方式进行更改。为了实现这个目标:
但是,这意味着在我们的开发环境中进行更改时,生产数据库不会发生任何更改,因为它们将被覆盖。
在其他任何事情之前,我有项目目录的备份(包括requirements.txt文件),数据库的备份 - 当然 - git
是我的朋友。
我需要dumpdata
备份以备不时之需,但它有一些 serius limitations有关内容类型,权限或其他情况{应该使用{3}}:
./manage.py dumpdata --exclude auth.permission --exclude contenttypes --exclude admin.LogEntry --exclude sessions --indent 2 > db.json
我使用pg_dump
备份:
pg_dump -U $user -Fc $database --exclude-table=django_migrations > path/to/backup-dir/db.dump
我从每个应用程序中删除所有迁移。
在我的情况下,migrations
文件夹是符号链接,因此我使用以下脚本:
#!/bin/bash
for dir in $(find -L -name "migrations")
do
rm -Rf $dir/*
done
我删除并重新创建数据库:
例如,bash脚本可以包含以下命令:
su -l postgres -c "PGPASSWORD=$password psql -c 'drop database $database ;'"
su -l postgres -c "createdb --owner $username $database"
su -l postgres -c "PGPASSWORD=$password psql $database -U $username -c 'CREATE EXTENSION $extension ;'"
我从转储中恢复数据库:
pg_restore -Fc -U $username -d $database path/to/backup-dir/db.dump
我按以下方式创建迁移:
./manage.py makemigrations <app1> <app2> ... <appn>
...使用以下脚本:
#!/bin/bash
apps=()
for app in $(find ./ -maxdepth 1 -type d ! -path "./<project-folder> ! -path "./.*" ! -path "./")
do
apps+=(${app#??})
done
all_apps=$(printf "%s " "${apps[@]}")
./manage.py makemigrations $all_apps
我使用虚假迁移进行迁移:
./manage.py migrate --fake
如果出现问题,一切都是***,(确实可能发生这种情况),我可以使用备份将所有内容恢复到以前的工作状态。如果我想使用第一步中的db.json
文件,它会是这样的:
我执行了以下步骤:
然后:
应用迁移:
./manage.py migrate
从db.json加载数据:
./manage.py loaddata path/to/db.json
然后我试着找出为什么我以前的努力没有成功。
成功执行步骤后,我将项目复制到服务器并对该框执行相同的操作。
这样,我始终保持最少的迁移次数,并且我可以将pg_dump
和pg_restore
用于共享同一项目的任何框。