使用json.dumps()的MemoryError

时间:2014-06-16 08:40:01

标签: python mysql json sqlalchemy out-of-memory

我想知道在将大型数组编码为json格式时,json.dump()json.dumps()中哪一个最有效。

你能告诉我一个使用json.dump()的例子吗?

实际上我正在制作一个Python CGI,它使用ORM SQlAlchemy从MySQL数据库中获取大量数据,并且在一些用户触发处理之后,我将最终输出存储在我最终转换为Json的数组中。

但是在转换为JSON时使用:

 print json.dumps({'success': True, 'data': data}) #data is my array

我收到以下错误:

Traceback (most recent call last):
  File "C:/script/cgi/translate_parameters.py", line 617, in     <module>
f.write(json.dumps(mytab,default=dthandler,indent=4))
  File "C:\Python27\lib\json\__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "C:\Python27\lib\json\encoder.py", line 209, in encode
    chunks = list(chunks)
MemoryError

所以,我的猜测是使用json.dump()按块转换数据。关于如何做到这一点的任何想法?

除了使用json.dump()之外的其他想法?

2 个答案:

答案 0 :(得分:7)

您可以简单地替换

f.write(json.dumps(mytab,default=dthandler,indent=4))

通过

json.dump(mytab, f, default=dthandler, indent=4)

这应该将数据“流”到文件中。

答案 1 :(得分:5)

JSON模块会在写入之前在内存中分配整个JSON字符串,这就是MemoryError发生的原因。

要解决此问题,请使用JSON.Encoder().iterencode()

with open(filepath, 'w') as f:
    for chunk in json.JSONEncoder().iterencode(object_to_encode):
        f.write(chunk)

但请注意,这通常需要一段时间,因为它是在很多小块中写的,而不是一次写入。

特例:

我有一个Python对象,它是一个dicts列表。像这样:

[
    { "prop": 1, "attr": 2 },
    { "prop": 3, "attr": 4 }
    # ...
]

我可以JSON.dumps()单个对象,但是转储整个列表会生成MemoryError为了加快写入速度,我打开了文件并手动编写了JSON分隔符:

with open(filepath, 'w') as f:
    f.write('[')

    for obj in list_of_dicts[:-1]:
        json.dump(obj, f)
        f.write(',')

    json.dump(list_of_dicts[-1], f)
    f.write(']')

如果你事先知道你的JSON对象结构,你可能会逃脱这样的事情。对于一般用途,只需使用JSON.Encoder().iterencode()