Python - 如何在 JSON 字符串中删除最后一个逗号(,)

5

你好,我刚开始尝试使用Python、Tornado和MongoDB做一些实验(我是新手)。我已经编写了一个简单的获取函数来获取我的MongoDB中的所有值,并以JSON格式返回。问题是当我尝试将输出写成JSON字符串时,我会在集合中的最后一条记录之后得到一个尾随逗号(,)。

class TypeList(APIHandler):
@gen.coroutine
def get(self):
    cursor = db.vtype.find()
    self.write("{"'"success"'": 1, "'"data"'":[")
    while (yield cursor.fetch_next):
        document = cursor.next_object()
        self.write(format(JSONEncoder().encode(document)))
        self.write(",")
    self.write("]}")

class JSONEncoder(json.JSONEncoder):
def default(self, o):
    if isinstance(o,ObjectId):
        return str(o)
    return json.JSONEncoder.default(self, o)

我的输出结果如下:
{"success": 1, "data":[{"_id": "55a5e988545779f35d3ecdf4", "name": "fgkd", "city": "fghj"},{"_id": 12345.0, "name": "adfs", "city": "asd"},]}

请问有人能告诉我如何去除最后一条记录后的逗号(,)?由于这个逗号,我得到了一个错误的JSON字符串。我已经尝试使用json dumps方法。

@gen.coroutine
def get(self):
    cursor = db.vtype.find({"brand": "Tata"})
    while (yield cursor.fetch_next):
        document = cursor.next_object()
        self.write(json.dumps(document,default=json_util.default))

我得到的输出为

{"Reg": "11ts", "_id": {"$oid": "55a5e988545779f35d3ecdf4"}, "Name": "Alex"}{"Reg": "12ts", "_id": {"$oid": "55a5eac6545779f35d3ecdf5"}, "Name": "asdf"}

当使用dumps[{"data":document}]时,我得到的输出是

[{"data": {"Name": "asdf", "Reg": "asdfs", "_id": {"$oid": "55a5e988545779f35d3ecdf4"}}}]

[{"data": {"Name": "qwer", "Reg": "asdff", "_id": {"$oid": "55a5eac6545779f35d3ecdf5"}}}]

但是我想要类似这样的输出结果。
{"data": [{"Name": "asdf", "Reg": "asdfs", "_id": {"$oid": "55a5e988545779f35d3ecdf4"}},{"Name": "qwer", "Reg": "asdff", "_id": {"$oid": "55a5eac6545779f35d3ecdf5"}}]}

如果我做错了什么,请告诉我,我不知道该怎么做。


实际上,在使用JSON dumps(json.dumps)时,我会收到一个错误消息:“ObjectId(addsfsfsf)”不可序列化为JSON。这个ObjectId来自我的mongodb。 - Tony Roczz
也许你的问题应该问关于那个。 - l'L'l
我已经编写了class JSONEncoder来解决序列化器问题。 - Tony Roczz
1
为什么要重复发明轮子呢;如果你已经解决了json.dumps()的问题,那么现在也许不需要费心思考这个了。 - l'L'l
为了解决JSON可序列化错误,我参考了以下链接:https://dev59.com/mWQn5IYBdhLWcg3wxZcn#16586277 - Tony Roczz
显示剩余2条评论
3个回答

7

没有理由通过文本拼接来构建JSON文档。

Python标准库中有一个非常好的json模块,你应该使用它。将你的文档构建为Python字典列表,然后使用json.dumps()将整个内容转换为有效的JSON。


1
使用self.write(json.dumps(document))时会出现错误TypeError: ObjectId('55a5e988545779f35d3ecdf4') is not JSON serializable。请问我是否正确使用了json.dumps,请指教。 - Tony Roczz
@TonyRoczz 这里的情感是正确的。但是你的mongodb库有一个定制版本的“dumps”。 - Blakes Seven
为了解决JSON可序列化错误,我已经参考 - Tony Roczz
使用PyMongo中的bson.json_util,它已经与Motor一起安装。 - A. Jesse Jiryu Davis

2

所以你的问题是关于 MongoDB 的 ObjectId?也许你应该使用 bson.json_util。它可能已经作为 MongoDB 驱动程序依赖的一部分安装了(它们都使用 pymongo ),但如果没有安装,则需要安装。

import bson
import bson.json_util
from bson.json_util import dumps
from bson import ObjectId

dumps({ "a": ObjectId() })

'{"a": {"$oid": "55a782261d41c80b0432b811"}}'

或者:

dumps([{ "a": ObjectId(), "b": 1 },{ "a": ObjectId(), "b": 2 }])
'[{"a": {"$oid": "55a79543268e150463d51799"}, "b": 1}, {"a": {"$oid": "55a79543268e150463d5179a"}, "b": 2}]'

它的工作方式与“dumps”完全相同,只是所有BSON类型处理都内置其中。

再次强调,这里没有必要重新发明轮子并“自己摸索”,因为人们已经在使用它了。


你能否只发布特定的字符串?我已经从bson.json_util导入了转储,但它给出了JSON不可序列化的错误。 - Tony Roczz
@TonyRoczz 编写了一个示例代码。输出支持"扩展 JSON",可以正确地标识字段的“类型”。文档中都有介绍。 - Blakes Seven
当我使用print而不是self.write时,转储功能正常。 - Tony Roczz
@TonyRoczz 很好。那就使用它吧。这里的信息是建立自己的字典,使用自然字典响应,并让其他东西处理序列化。就像 CSV 一样,这并不新鲜,所以之前都已经做过了。 - Blakes Seven
谢谢。上面的例子是可以工作的,但问题在于它不能区分表格中不同的记录,输出结果如下:{"type": "adfs", "_id": 12345.0, "brand": "asd"}{"type": "adfs", "_id": 12345.0, "brand": "asd"}。在不同的记录之间应该有逗号,否则它就不是一个正确的JSON字符串。难道在两个记录之间不应该有逗号来分隔吗? - Tony Roczz
显示剩余2条评论

0

你的JSONEncoder实现得很好。按照预期的方式使用它:

>>> JSONEncoder().encode({'data': [ObjectId(), ObjectId()]})
'{"data": ["<objId>", "<objId>"]}'

编码器将负责序列化字典、对象、列表、元组、字符串(包括Unicode)、整数、长整型、浮点型、布尔值和 None。您的实现还会考虑 ObjectId。太棒了!

只需放弃字符串连接,使用 encode 即可。


请问您能否指导我如何编写这段代码?您认为我的JSONEncoder().encode(document)语句应该怎么写呢?非常感谢您的帮助。 - Tony Roczz
我认为Blake的答案更好,但如果你想保留JSONEncoder,你可以尝试类似于JSONEncoder().encode({'success': 1, 'data': items})的方法,其中items是查询返回的文档列表。你可以一次性获取它们所有,或使用现有的循环来填充一个最初为空的数组。 - André Laszlo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接