[英]Building large xml file with python 2
我正在尝试在Python 2 / Django中构建大型XML文件时获得最佳性能。
最终的XML文件约为500mb。 第一种方法是使用lxml ,但是花费了超过3.5个小时。 我使用xml.sax(XMLGenerator)进行了测试,并花费了大约相同的时间,即3.5个小时。
我试图找到内存消耗最少的最快方法。 我搜寻了几天以寻找最佳解决方案,但没有成功。
lxml代码:
from lxml import etree
tree_var = etree.Element("tree_var", version='1.2')
DATE = etree.SubElement(DATETIME, "DATE")
DATE.text = datetime.date.today().strftime('%Y-%m-%d')
products = FromModel.objects.all().values_list('product_id')
for product in products:
if product.state == 'new':
ARTICLE = etree.SubElement(tree_var, "ARTICLE", mode=product.state)
XMLGenerator代码:
from xml.sax.saxutils import XMLGenerator
from xml.sax.xmlreader import AttributesNSImpl
with open("tmp/" + filename + ".xml", 'wb') as out:
g = XMLGenerator(out, encoding='utf-8')
g.startDocument()
def start_tag(name, attr={}, body=None, namespace=None):
attr_vals = {}
attr_keys = {}
for key, val in attr.iteritems():
key_tuple = (namespace, key)
attr_vals[key_tuple] = val
attr_keys[key_tuple] = key
attr2 = AttributesNSImpl(attr_vals, attr_keys)
g.startElementNS((namespace, name), name, attr2)
if body:
g.characters(body)
def end_tag(name, namespace=None):
g.endElementNS((namespace, name), name)
def tag(name, attr={}, body=None, namespace=None):
start_tag(name, attr, body, namespace)
end_tag(name, namespace)
g.endDocument()
我很确定xml.sax使用的内存更少,并且实时增加了文件数量。 另一方面,lxml仅在循环结束时使用巨大的缓冲区创建文件。
有帮助的想法吗?
谢谢!
阅读时,您可能仍在加载整个输入文件。 您可以尝试以下方式,以逐步读取文件为例。 这个 stackoverflow问题还提供了比下面的代码片段更多的上下文。 您还可以在iterparse()
指定一个目标元素,以便可以一次转储整个目标元素。
for event, elem in etree.iterparse(in_file, events=('start', 'end',)):
if event == 'start':
start_tag(elem.tag, {}, elem.text)
elif event == 'end':
end_tag(elem.tag)
# It's safe to call clear() here because no descendants will be accessed
elem.clear()
# Also eliminate now-empty references from the root node to elem
while elem.getprevious() is not None:
del elem.getparent()[0]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.