努力使用jsonlines

时间:2018-04-10 08:29:21

标签: python json jsonlines

我在使用jsonlines解析请求正文时遇到问题。我正在使用龙卷风作为服务器,这发生在post()方法中。 我的目的是将请求的主体解析为单独的JSON,然后使用jsonlines Reader迭代它们,对每个执行一些工作然后将它们推送到数据库。 我通过将utf-8编码的主体转储到文件中然后使用:

来解决了这个问题
with jsonlines.open("temp.txt") as reader:

这对我有用。我可以用

遍历整个文件
for obj in reader:

我只是觉得这是一个不必要的开销,如果我能理解是什么让我不再使用这段代码而可以减少:

log = self.request.body.decode("utf-8")
with jsonlines.Reader(log) as reader:
   for obj in reader:

我得到的例外是:

  

jsonlines.jsonlines.InvalidLineError:行包含无效的json:   期望用双引号括起来的属性名称:第1行第2列   (char 1)(第1行)

我在这里尝试搜索此错误,我发现的所有内容都是人们尝试使用格式错误的jsons而不是双引号的示例。对我来说情况并非如此。我调试了请求,发现从decode方法返回的字符串确实有两个属性和值的双引号。

这是我发送的请求正文的示例(这是Postman中的样子):

{"type":"event","timestamp":"2018-03-25 09:19:50.999","event":"ButtonClicked","params":{"screen":"MainScreen","button":"SettingsButton"}} 
{"type":"event","timestamp":"2018-03-25 09:19:51.061","event":"ScreenShown","params":{"name":"SettingsScreen"}} 
{"type":"event","timestamp":"2018-03-25 09:19:53.580","event":"ButtonClicked","params":{"screen":"SettingsScreen","button":"MissionsButton"}} 
{"type":"event","timestamp":"2018-03-25 09:19:53.615","event":"ScreenShown","params":{"name":"MissionsScreen"}}

您可以通过在post方法中使用这个简单的代码并发送我通过Postman提供的行来重现异常:

log = self.request.body.decode("utf-8")
with jsonlines.Reader(log) as currentlog:
    for obj in currentlog:
        print("obj")

作为旁注:邮递员将数据作为文本发送,而不是JSON。

如果您需要更多信息来回答此问题,请告知我们。 我注意到的一件事是从decode方法返回的字符串以一个引号开始和结束。我想这是因为JSON本身的双引号。它有什么关系吗? 一个例子:

'{"type":"event","timestamp":"2018-03-25 09:19:50.999","event":"ButtonClicked","params":{"screen":"MainScreen","button":"SettingsButton"}}'

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

jsonlines.Reader接受iterable作为arg(“第一个参数必须是一个可以产生JSON编码字符串的迭代”而不是像你的例子中那样用json编码的单个字符串),但是,在.decode("utf-8")之后,记录将是一个字符串,恰好支持可迭代接口。因此,当读者在引擎next(log)下进行调用时,它将获得日志字符串的第一项,即字符{,并将尝试将其作为json-line处理,这显然是无效的。在将日志传递给Reader之前尝试log = log.split()