【问题标题】:Python yield JSON docs from a streamPython 从流中生成 JSON 文档
【发布时间】:2014-04-01 12:25:25
【问题描述】:

我有一个 REST API (RavenDB's Query Streaming),它以 JSON 格式返回 很多 数据。一口气加载到内存中解析太多了:

问题在于,它不是“每行一个文档”,这很容易,而是在一个名为“结果”的字段中返回一个包含我们文档的单个字符串,如下所示:

{"Results":[
  {"Name":"Hello World"}
]}

我真正想做的是使用 python 的请求库来流式传输响应,如下所示:

r = requests.get('.../streams/query/Raven/DocumentsByEntityName?query=', stream=True)
for chunk in r.iter_content(chunk_size=512, decode_unicode=False):
    print chunk

但我想生成单独的 JSON 文档,以便不必解析整个响应。一次生成一个 JSON 文档的最有效方法是什么?

【问题讨论】:

    标签: python json ravendb


    【解决方案1】:

    json.load() 有一个可选的object_pairs_hook 参数,您可以使用它。这个想法是捕获每个内部dict,随着它的进行,从你的回调函数返回一个空字典(或者可能是None),以避免在内存中建立巨大的数据结构。

    请记住,这不是性能优化:在我的测试中(使用import simplejson as json),我发现虽然我可以节省内存,但使用钩子检查每个元素实际上会使解析速度慢几倍。不过,如果你内存不足,总比没有好。

    【讨论】:

    • 你能告诉我一个例子,说明如何只产生来自 {"Results":[{}]} 的内部字典?
    【解决方案2】:

    这是我目前的处理方式。我正在做的是匹配大括号 ({}),以便我可以输出 just 内部 JSON 文档,每行一个(参见:JSON Lines)。

    这让我能够将输出流式传输到一个文本文件,我可以在以后逐行解码,而不必解码内存中的整个项目。

    欢迎任何建议或优化!

    def yield_stream(url1 = '/streams/query/Raven/DocumentsByEntityName?query=', query1=''):
        r = requests.get(conf.db + url1 + query1, auth=conf.db_auth, stream=True)
        i = 0
        is_doc = False
        is_str = False
        doc1 = []
        for chunk in r.iter_content(chunk_size=1024, decode_unicode=True):
            for char in chunk:
                if is_doc:
                    doc1.append(char)
    
                if doc1[-2:-1] != ['\\'] and doc1[-1:] == ['"']:
                    is_str = not is_str
    
                if char == '{' and not is_str: 
                    i += 1
                    if i == 2:
                        doc1.append(char)
                        is_doc = True
    
                if char == '}' and not is_str: 
                    i -= 1
                    if i == 1:
                        yield ''.join(doc1)
                        doc1 = []
                        is_doc = False
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-24
      • 2011-08-29
      • 2016-03-24
      • 1970-01-01
      • 2019-08-26
      • 2020-08-25
      • 1970-01-01
      • 2015-06-22
      相关资源
      最近更新 更多