【问题标题】:Django - Populating a database for test purposesDjango - 为测试目的填充数据库
【发布时间】:2010-12-23 20:56:36
【问题描述】:

我需要用一堆虚拟条目(大约 200 多个)填充我的数据库,以便我可以测试我制作的管理界面,我想知道是否有更好的方法来做到这一点。昨天我花了大部分时间尝试手工填写(即通过将 my_model(title="asdfasdf", field2="laksdj"... 之类的东西包装起来)在一堆“for x in range( 0,200):" 循环)并放弃了,因为它没有按我预期的方式工作。我认为this 是我需要使用的,但您不需要在数据库中拥有(现有)数据才能使其工作吗?

【问题讨论】:

  • 你不想序列化。您想通过在 shell 中运行来创建初始数据,保存实例,然后使用 loaddata 以 json 之类的格式将数据库导出到固定装置:python manage.py dumpdata --format=json --indent=4 appname@Matthew Schinckel 最接近这一点。

标签: python database django


【解决方案1】:

检查这个应用程序

https://github.com/aerosol/django-dilla/

假设您在 Django 中编写了您的博客应用程序(哦,是的,您最喜欢的!)。单元测试很顺利,一切都运行得非常快,即使是那些 ORM 生成的超长查询。您已经添加了几个分类帖子,但它仍然很稳定。您非常确定该应用程序是高效的并且可以进行实时部署。正确的?错误的。

【讨论】:

  • 这正是我一直在寻找的东西。非常感谢!
  • @Eeyore:你的回复让我睡不着。
【解决方案2】:

您可以为此目的使用固定装置,以及 loaddata 管理命令。

一种方法是这样做。

  1. 准备您的测试数据库。

  2. 使用 dumpdata 创建数据库的 JSON 导出。

  3. 把它放在你的应用程序的fixtures目录中。

  4. 编写单元测试来加载这个“夹具”:https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TransactionTestCase.fixtures

【讨论】:

【解决方案3】:

Django fixtures 提供了一种在syncdb 上导入数据的机制。但是,通过 Python 代码执行此初始数据传播通常更容易。您概述的技术应该可以通过 syncdb 或管理命令起作用。例如,通过syncdb,在my_app/management.py

def init_data(sender, **kwargs):
    for i in range(1000):
        MyModel(number=i).save()

signals.post_syncdb.connect(init_data)

或者,在management commandmyapp/management/commands/my_command.py

from django.core.management.base import BaseCommand, CommandError

from models import MyModel

class MyCommand(BaseCommand):
    def handle(self, *args, **options):
        if len(args) > 0:
            raise CommandError('need exactly zero arguments')

        for i in range(1000):
            MyModel(number=i).save()

然后您可以将此数据导出到夹具,或使用管理命令继续导入。如果您选择继续使用syncdb 信号,您需要有条件地运行init_data 函数以防止在后续syncdb 调用中导入数据。当一个夹具不够用时,我个人喜欢两者都做:创建一个管理命令来导入数据,但让第一个 syncdb 调用自动执行导入。这样,部署更加自动化,但我仍然可以轻松地修改初始数据并重新运行导入。

【讨论】:

    【解决方案4】:

    我不确定您为什么需要任何序列化。只要您已将 Django settings.py 文件设置为指向您的测试数据库,填充测试数据库应该只是保存模型。

    for x in range(0, 200):
        m = my_model(title=random_title(), field2=random_string(), ...)
        m.save()
    

    有更好的方法来做到这一点,但如果你想要一个快速的测试集,这是要走的路。

    【讨论】:

    • 你是在shell的上下文中运行的,对吧? python manage.py shell
    【解决方案5】:

    已接受答案推荐的应用不再维护,但 django-seed 可以用作替代品:

    https://github.com/brobin/django-seed

    【讨论】:

      【解决方案6】:

      我会向你推荐django-autofixtures。我尝试了 django_seed 和 django-autofixtures,但是 django_seed 在唯一键方面存在很多问题。 django-autofixtures 在填充数据库时处理唯一、主要和其他数据库约束

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-27
        • 1970-01-01
        • 2021-02-01
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 1970-01-01
        • 2019-01-17
        相关资源
        最近更新 更多