使用json.dumps()的MemoryError

sal*_*mey 4 python mysql json sqlalchemy out-of-memory

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

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

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

但是当转换为JSON时:

 print json.dumps({'success': True, 'data': data}) #data is my array
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

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

或者除了使用其他想法json.dump()

seb*_*ian 9

你可以简单地替换

f.write(json.dumps(mytab,default=dthandler,indent=4))
Run Code Online (Sandbox Code Playgroud)

通过

json.dump(mytab, f, default=dthandler, indent=4)
Run Code Online (Sandbox Code Playgroud)

这应该将数据"流"化到文件中.


Xav*_* Ho 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)
Run Code Online (Sandbox Code Playgroud)

但是请注意,这通常需要花费相当长的时间,因为它是在编写许多小块而不是一次完成所有内容。


特殊情况:

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

[
    { "prop": 1, "attr": 2 },
    { "prop": 3, "attr": 4 }
    # ...
]
Run Code Online (Sandbox Code Playgroud)

我可以创建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(']')
Run Code Online (Sandbox Code Playgroud)

如果您事先知道JSON对象结构,则可能可以避免类似的事情。对于一般用途,只需使用即可JSON.Encoder().iterencode()

  • 是的,但是如果您尝试大型对象, iterencode() 太慢 - 最好将块划分到内存可以处理的位置,然后立即将其全部传递给encode()。 (2认同)