编程语言
首页 > 编程语言> > python – 具有dumpdata和迁移的Django备份策略

python – 具有dumpdata和迁移的Django备份策略

作者:互联网

this question一样,我为我的数据库设置了基于dumpdata的备份系统.该设置类似于运行调用dumpdata的cron脚本并将备份移动到远程服务器,目的是简单地使用loaddata来恢复数据库.但是,我是not sure this plays well with migrations.loaddata现在有一个ignorenonexistent交换机来处理已删除的模型/字段,但它无法解决使用一次性默认值添加列或应用RunPython代码的情况.

我看到它的方式,有两个子问题需要解决:

>使用每个应用程序的当前版本标记每个dumpdata输出文件
>将夹具拼接到迁移路径中

我不知道如何在不引入大量开销的情况下解决第一个问题.是否足以为每个包含{app_name:migration_number}映射的备份保存额外文件?

一旦第一个问题得到解决,我认为第二个问题就更容易了,因为这个过程大致是:

>创建一个新数据库
>将迁移向前运行到每个应用的适当位置
>使用给定的fixture文件调用loaddata
>运行其余的迁移

this question中有一些代码(从错误报告中链接),我认为可以为此目的进行调整.

由于这些是数据库的相当规则/大型快照,因此我不希望将它们作为数据迁移使迁移目录混乱.

解决方法:

我正在采取以下步骤在我的项目的任何实例之间备份,恢复或传输我的postgresql数据库:

我们的想法是保持尽可能少的迁移,就像第一次在空数据库上运行manage.py makemigrations一样.

假设我们的开发环境有一个工作数据库.此数据库是生产数据库的当前副本,不应对任何更改开放.我们添加了模型,更改了属性等,这些操作已经生成了额外的迁移.

现在,数据库已准备好迁移到生产环境 – 如前所述 – 不向公众开放,因此不会以任何方式进行更改.为了实现这个目标:

>我在开发环境中执行正常的过程.
>我将项目复制到生产环境.
>我执行生产环境的正常程序

但是,这意味着当我们在开发环境中进行更改时,生产数据库不会发生任何更改,因为它们将被覆盖.

正常程序

在其他任何事情之前,我有一个项目目录的备份(其中包括一个requirements.txt文件),数据库的备份和 – 当然 – git是我的一个朋友.

>我需要一个dumpdata备份以备不时之需,但它有一些关于内容类型,权限或其他应使用natural foreignkey的情况的limitations

./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

>我删除了每个应用程序的所有迁移.

在我的例子中,迁移文件夹是符号链接,因此我使用以下脚本:

#!/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文件,它会像这样:

当pg_dump或pg_restore失败时

我执行的步骤:

> 3(删除迁移)
> 4(删除并重新创建数据库)
> 6(makemigrations)

然后:

>应用迁移:

./manage.py migrate

>从db.json加载数据:

./manage.py loaddata path/to/db.json

然后我试着找出为什么我之前的努力没有成功.

成功执行这些步骤后,我将项目复制到服务器并对该框执行相同的操作.

这样,我总是保持最少的迁移次数,并且我能够将pg_dump和pg_restore用于共享同一项目的任何框.

标签:python,django,backup,django-migrations,dumpdata
来源: https://codeday.me/bug/20190523/1156659.html