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

Fel*_*ipe 5 python django backup dumpdata django-migrations

这个问题中,我dumpdata为我的数据库设置了一个基于备份的系统.该设置类似于运行调用dumpdata并将备份移动到远程服务器的cron脚本,目的是简单地使用loaddata恢复数据库.但是,我不确定它是否适合迁移.loaddata现在有一个ignorenonexistent开关来处理已删除的模型/字段,但它无法解决使用一次性默认值或应用RunPython代码添加列的情况.

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

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

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

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

  1. 创建一个新数据库
  2. 将迁移运行到每个应用程序的适当位置
  3. loaddata使用给定的fixture文件调用
  4. 运行其余的迁移

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

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

rar*_*iru 7

我正在按照以下步骤在项目的任何实例之间备份,还原或转移我的postgresql数据库:

这样做的目的是使迁移尽可能少,就像manage.py makemigrations第一次在空数据库上运行一样。

假设我们有一个适用于我们开发环境的数据库。该数据库是生产数据库的当前副本,不应对其进行任何更改。我们添加了模型,更改了属性等,并且这些操作产生了额外的迁移。

现在,数据库已准备好迁移到生产环境(如前所述),该生产环境不对公众开放,因此不会进行任何更改。为了实现这一点:

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

我们在开发环境中进行更改。生产数据库中不应发生任何更改,因为它们将被覆盖

正常程序

首先,我有一个项目目录的备份(其中包括一个requirements.txt文件),一个数据库的备份,并且-当然- git是我的朋友。

  1. 如果需要我会dumpdata备份。但是,在内容类型,权限或应使用自然外键的其他情况下,dumpdata存在一些严重 限制

    ./manage.py dumpdata --exclude auth.permission --exclude contenttypes  --exclude admin.LogEntry --exclude sessions --indent 2 > db.json
    
    Run Code Online (Sandbox Code Playgroud)
  2. pg_dump备份使用:

    pg_dump -U $user -Fc $database --exclude-table=django_migrations > path/to/backup-dir/db.dump
    
    Run Code Online (Sandbox Code Playgroud)
  3. 仅当我要合并现有迁移时,才从每个应用程序中删除所有迁移。

    在我的情况下,该migrations文件夹是一个符号链接,因此我使用以下脚本:

    #!/bin/bash
    for dir in $(find -L -name "migrations")
    do
      rm -Rf $dir/*
    done
    
    Run Code Online (Sandbox Code Playgroud)
  4. 我删除并重新创建数据库:

    例如,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 ;'"
    
    Run Code Online (Sandbox Code Playgroud)
  5. 我从转储中还原数据库:

    pg_restore -Fc -U $username -d $database path/to/backup-dir/db.dump
    
    Run Code Online (Sandbox Code Playgroud)
  6. 如果在步骤3中删除了迁移,则可以通过以下方式重新创建它们:

    ./manage.py makemigrations <app1> <app2> ... <appn>
    
    Run Code Online (Sandbox Code Playgroud)

    ...通过使用以下脚本:

    #!/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
    
    Run Code Online (Sandbox Code Playgroud)
  7. 我使用假迁移进行迁移:

    ./manage.py migrate --fake
    
    Run Code Online (Sandbox Code Playgroud)

万一出了什么问题,而一切都变成了***,(这确实有可能发生),我可以使用备份将一切恢复到先前的工作状态。如果我要使用db.json第一步中的文件,它将如下所示:

当pg_dump或pg_restore失败时

我执行以下步骤:

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

然后:

然后,我尝试找出为什么以前的努力没有成功。

成功执行步骤后,我将项目复制到服务器,然后在该框中执行相同的操作。

这样,我始终将迁移次数保持在最少,并且我能够使用pg_dump和迁移pg_restore到共享同一项目的任何设备。

  • @JulienGreard鉴于[migrations](https://docs.djangoproject.com/en/2.1/topics/migrations/)非常微妙且[很多次](https:// docs .djangoproject.com / en / 2.1 / topics / migrations /#data-migrations)无法自动复制。但是,其想法是在应用所有迁移后,备份数据库,删除所有内容并重新安装。类固醇上的[squahing](https://docs.djangoproject.com/en/dev/topics/migrations/#migration-squashing)之类的东西……当项目已经部署时不是很有用,但生气时会很性感! (2认同)