[英]Django ORM: Organizing massive amounts of data, the right way
我有一个使用django-piston将XML提要发送到内部客户端的Django应用。 通常,这些工具工作得很好,但是我们有一些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时,它变得不可靠并且超时。
我尝试过的
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.