Python - 使用大型Dict时进程消失和冻结?

时间:2013-08-28 21:42:24

标签: python xml dictionary urllib

我正在处理大小约为85MB的XML文件。目前我只是想处理一个。我正在做的是下载一个zip,解压缩到磁盘,然后将XML转换为Python Dict,更改一些东西,然后保存Dict,并将其发送到MongoDB。除非我转换为Python dict,否则进程会冻结/消失..

我在使用Ubuntu 13.04服务器,4核2.6,26GB RAM和1TB 15,000RPM的VM上运行此脚本。我正在监视脚本运行,基本上python在7分钟内占用了12%的内存,然后消失了,进程从我的高使用率列表中掉了下来,我的终端管道就不动了。我用CTRL + Z杀了它并返回“写入失败:断管”

在终端上打印的最后一件事是“转换dailyprice_0505_eur.xml.zip”,这让我怀疑可能有xmltodict的东西,但老实说我坚持了。带有数据的示例代码应该适用于任何愿意帮我测试的人。任何帮助表示赞赏!感谢。

#Importing
import urllib, xmltodict, os
from zipfile import ZipFile

#Getting Working Dir
abspath = os.path.abspath(__file__)
root = os.path.dirname(abspath) + "/"
print "Current Working Directory: " + root

#Defining
urlAuth = 'https://dl.dropboxusercontent.com/u/9235267/'
dailypriceFL = ['dailyprice_0505_eur.xml.zip']
dailyPriceDict = {}

for x in dailyPriceFL:
    print '  * Downloading',x
    urllib.urlretrieve(urlAuth+x, x)

    print '  * Extracting',x
    with ZipFile(x, "r") as z:
        z.extractall(root)

    print '  * Converting',x
    f = open(root+x.replace(".zip",""))
    data = xmltodict.parse(f.read())
    f.close()

    print '  * Adding Currency to Dict',x
    for y in data['prices']['price']:
        y.update({"currency": x[-7:].replace(".xml","").upper()})

    print '  * Ammending',x
    dailyPriceDict.update(data)

    print '  * Deleting',x
    os.remove(root+x)
    os.remove(root+x.replace(".zip",""))
    print '  * Finished',x

1 个答案:

答案 0 :(得分:0)

我不知道你列出的规格是不是内存错误。当我尝试在xml.dom.minidom中加载XML时,我得到了这个:

Traceback (most recent call last):
  File "c:\python27\lib\xml\dom\minidom.py", line 1930, in parseString
    return expatbuilder.parseString(string)
  File "c:\python27\lib\xml\dom\expatbuilder.py", line 940, in parseString
    return builder.parseString(string)
  File "c:\python27\lib\xml\dom\expatbuilder.py", line 223, in parseString
    parser.Parse(string, True)
  File "c:\python27\lib\xml\dom\expatbuilder.py", line 751, in start_element_handler
    node = minidom.Element(qname, uri, prefix, localname)
  File "c:\python27\lib\xml\dom\minidom.py", line 653, in __init__
    self._attrs = {}   # attributes are double-indexed:
MemoryError

这似乎在我的方面起作用了:

>>> import xmltodict, os
>>> data = open('price.xml').read()
>>> xml = xmltodict.parse(data)
>>> xml['prices']['price'][0]
OrderedDict([(u'code', u'AD1550.301.1'), 
             (u'startdate', u'2013-08-24'), 
             (u'enddate', u'2013-09-30'), 
             (u'rentalprice', u'126.00'), 
             (u'midweekrentalprice', u'0.00'), 
             (u'weekendrentalprice', u'0.00'), 
             (u'fixprice', u'0.00')])

我的系统确实需要接近800Mb,但我似乎没有出错。但是,如果我尝试在之后将其解析为xmltodict ,我试图使用minidom,我会得到更像这样的东西:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python27\lib\site-packages\xmltodict.py", line 228, in parse
    parser.Parse(xml_input, True)
xml.parsers.expat.ExpatError: out of memory: line 1, column 0

这直接暗示,因为两者都基于expat,所以在你的脚本运行(或循环的迭代)之间没有释放出某些东西,你需要以某种方式重构。