繁体   English   中英

使用python 2构建大型xml文件

[英]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.

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