繁体   English   中英

Django ORM:以正确的方式组织大量数据

[英]Django ORM: Organizing massive amounts of data, the right way

我有一个使用django-piston将XML提要发送到内部客户端的Dj​​ango应用。 通常,这些工具工作得很好,但是我们有一些XML提要目前运行超过15分钟。 这会导致超时,并且提要变得不可靠。

我正在尝试思考可以改善此设置的方法。 如果需要对数据进行一些重组,那也是可能的。

这是当前数据收集的外观:

class Data(models.Model)
     # fields

class MetadataItem(models.Model)
     data = models.ForeignKey(Data)

# handlers.py
data = Data.objects.filter(**kwargs)

for d in data:
   for metaitem in d.metadataitem_set.all():
       # There is usually anywhere between 55 - 95 entries in this loop
       label = metaitem.get_label() # does some formatting here
       data_metadata[label] = metaitem.body

显然,该程序的核心工作更多,但我只是指出问题所在。 当我们的data列表为300时,它变得不可靠并且超时。

我尝试过的

  • 获取所有数据ID的集合,然后执行单个大型查询以获取所有MetadataItem 最后,在我的循环中过滤它们。 这是为了保留确实减少的一些查询。
  • 使用.values()减少模型实例的开销,这确实加快了速度,但幅度不大。

一个想法我想一个简单的解决方案,这是写在步缓存。 因此,减少了超时时间; 我会写前50个数据集,保存到缓存,调整一些计数器,写下50个,依此类推。仍然需要考虑一下。

希望有人可以帮助我朝正确的方向前进。

您发布的代码段中的问题是Django不包含通过反向关系自动连接的对象,因此您必须对每个对象进行查询。 丹尼尔·罗斯曼Daniel Roseman)在他的博客中指出 ,这是一种很好的解决方法!

如果这不能很好地解决您的问题,您还可以尝试在一个原始sql查询中获取所有内容...

通过首先获取所有数据ID,然后使用select_related在单个大查询中获取数据及其元数据,您可以进一步减少查询数量。 这将大大减少查询的数量,但是查询的大小可能不切实际/太大。 就像是:

data_ids = Data.objects.filter(**kwargs).values_list('id', flat = True)
for i in data_ids:
    data = Data.objects.get(pk = i).select_related()
    # data.metadataitem_set.all() can now be called without quering the database
    for metaitem in data.metadataitem_set.all():
        # ...

但是,如果可能的话,我建议从Web服务器外部的某个地方预先计算提要。 如果结果小于1 MB,则可以将结果存储在memcache中。 或者,您也可以成为新手,将结果存储在像Redis这样的“ NoSQL”数据库中。 或者,您可以将其写入磁盘上的文件中。

如果可以更改数据的结构,也许还可以更改数据存储?

实际上,允许某些结构(例如CouchDB或MongoDB)的“ NoSQL”数据库在这里很有用。

假设每个Data项目都有一个文档。 该文档将具有您的常规字段。 您还将添加一个“元数据”字段,该字段是元数据列表。 那么以下数据结构呢:

{
    'id': 'someid',
    'field': 'value',
    'metadata': [
        { 'key': 'value' },
        { 'key': 'value' }
    ]
}

然后,您将能够轻松地访问数据记录并获取所有元数据。 为了进行搜索,将索引添加到“数据”文档中的字段。

我在Erlang / OTP中使用Mnesia的系统上工作,该系统基本上是具有一些索引和帮助程序的键值数据库。 我们大量使用嵌套记录来取得巨大成功。

我将其添加为单独的答案,因为它与另一个完全不同。

另一个想法是使用Celery(www.celeryproject.com),这是用于python和django的任务管理系统。 您可以使用它异步执行任何长时间运行的任务,而无需按住主应用程序服务器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM