复制部分生产Django数据库到本地或暂存环境

8
我有一个带有3个环境(本地、预备、生产)的Django网站。
生产环境包含一些数据,我不想让我的开发人员访问到(用户的个人数据和财务数据)。
考虑到合规原因,备份恢复数据库不是一个选项。
但我们在这个网站上也有一些内容页面,我们使用Wagtail CMS进行管理。
我正在寻找一种方法,可以在需要时将生产环境的数据(仅同步某些模型,但具体是Wagtail页面)同步回预备和开发人员的本地环境。
理想情况下,我希望有一个可在其他环境中运行的manage命令来复制数据:
例如:./ manage.py sync_from_prod BlogPost ,它会查找本地或预备环境中所有缺少的博客文章,并在数据库中创建它们。 我找不到任何库可以为Wagtail或Django实现此功能。
这似乎是一个常见的问题,我很惊讶没有Stackoverflow问题或开源库解决此问题。
如果不存在,则可能尝试编写自己的django-model-sync(发现这个项目,但它已经三年了,兼容django 1.7,而我是在python3 django 1.11上)。
为了管理安全性,开发人员可以使用秘密访问生产API(通过ssl)暴露数据。

五年后,我将解释我现在如何做到这一点:我的数据库位于CloudSQL(谷歌),我有一个github操作,下载生产环境的转储文件并将其加载到本地数据库中,执行一个管理命令来清理数据并删除PII,然后将其转储到Google Cloud存储桶中,开发人员可以下载并在本地加载。 - Benos
3个回答

4
您可以使用命令dumpdata复制您想要的模型。
在生产中,使用以下命令./manage.py dumpdata app_name.model_name > model_name.json。这将保存所选数据库表的所有数据到文件model_name.json中。 然后,在本地或演练服务器上,使用以下命令为此文件执行loaddata./manage.py loaddata model_name.json
你可以在这里阅读更多信息:https://the-bosha.ru/2016/06/29/django-delaem-damp-bazy-dannykh-i-vosstanavlivaem-iz-nego-s-dumpdata-i-loaddata/ (仅限俄语指南)

加载时出现了错误信息。我查了一下,我认为使用dumpdata的正确方法是用“--output”而不是“>”。 ./manage.py dumpdata app_name.model_name --output model_name.json - Werner Trelawney

2

我曾经在dumpdata / loaddata上遇到了很大的困难,必须从各种来源组合答案,所以最后我会写一个简短的总结:

  1. 在生产环境中: ./manage.py dumpdata -e contenttypes -e auth.Permission --output data.json
  2. 在开发环境中: 清空你的数据库 ./manage.py flush,如果清空不起作用,请参见下文
  3. 在开发环境中: ./manage.py loaddata data.json

如果由于Dev上的某些数据不一致而无法刷新:

  1. 删除db文件
  2. 除了迁移文件夹中的初始文件外,删除所有文件 rm */migrations/0*.py
  3. ./manage.py migrations && ./manage.py migrate

然后您应该能够加载数据


0

你可以在生产环境中使用dumpdata命令(或扩展该命令)来获取博客数据的JSON导出,然后在本地环境中使用loaddata命令保存。

如何实现工作流完全取决于您,例如,您可能希望在生产环境中将dumpdata命令包装在受保护的API中,然后在本地环境中创建/运行一个sync_from_prod命令来调用该API并执行call_command('loaddata', 'data_file.json')命令,使用从生产环境导出的JSON数据。

伪代码:

# the api view to provide the data on prod
def dumpdata_view(requst):
    output = StringIO.StringIO()
    call_command('dumpdata', output=output)
    output.seek(0)
    return JsonResponse(output.readlines()

# command to execute locally
class sync_from_prod(BaseCommand):
    def handle(self, *args, **kwargs):
        with open('data_file.json', 'w') as f:
            data = requests.get('https://prod/api/dumpdata?model=BlogPost')
            f.write(data.content)
        call_command('loaddata', 'data_file.json')

2
转储数据的问题在于您无法控制所获取的数据(没有过滤器,也没有用于转换个人身份识别数据点的钩子)。 - Benos
1
我理解你只想从生产环境同步BlogPost。混淆数据的部分是另一个问题。 - James Lin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接