gpt4 book ai didi

python - 带有转储数据和迁移的 Django 备份策略

转载 作者:太空狗 更新时间:2023-10-30 01:13:29 24 4
gpt4 key购买 nike

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

在我看来,有两个子问题需要解决:

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

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

第一个问题解决了,第二个问题我觉得比较容易,因为过程大致是这样的:

  1. 创建一个新的数据库
  2. 为每个应用程序向前运行迁移到适当的点
  3. 使用给定的夹具文件调用loaddata
  4. 运行其余的迁移

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

由于这些是数据库的相当常规/大的快照,我不想将它们作为数据迁移保留在迁移目录中。

最佳答案

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

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

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

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

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

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

正常程序

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

  1. 我做了一个dumpdata 备份以备不时之需。但是,dumpdata 有一些严重 limitations关于内容类型、权限或其他情况 natural foreignkey应该使用:

    ./manage.py dumpdata --exclude auth.permission --exclude contenttypes  --exclude admin.LogEntry --exclude sessions --indent 2 > db.json
  2. 我使用了一个 pg_dump 备份:

    pg_dump -U $user -Fc $database --exclude-table=django_migrations > path/to/backup-dir/db.dump
  3. 只有当我想将现有迁移合并为一个时,我才会从每个应用程序中删除所有迁移。

    在我的例子中,migrations 文件夹是一个符号链接(symbolic link),所以我使用以下脚本:

    #!/bin/bash
    for dir in $(find -L -name "migrations")
    do
    rm -Rf $dir/*
    done
  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 ;'"
  5. 我从转储中恢复数据库:

    pg_restore -Fc -U $username -d $database path/to/backup-dir/db.dump
  6. 如果迁移在第 3 步中被删除,我将按以下方式重新创建它们:

    ./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
  7. 我使用假迁移进行迁移:

    ./manage.py migrate --fake

如果出现完全错误并且一切都是 ***,(这确实会发生),我可以使用备份将一切恢复到之前的工作状态。如果我想使用第一步中的 db.json 文件,它是这样的:

当 pg_dump 或 pg_restore 失败时

我执行以下步骤:

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

然后:

  • 应用迁移:

    ./manage.py migrate
  • 从 db.json 加载数据:

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

然后我试图找出我之前的努力没有成功的原因。

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

这样,我始终保持最少的迁移次数,并且我能够对共享同一项目的任何框使用 pg_dumppg_restore

关于python - 带有转储数据和迁移的 Django 备份策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34822002/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com