Pet*_*aur 22 python json mongodb bson
所以我从MongoDB转储中获得了大量的.bson.我在命令行上使用bsondump,将输出作为stdin传递给python.这成功地从BSON转换为'JSON',但它实际上是一个字符串,看似不合法的JSON.
例如,传入的行看起来像这样:
{ "_id" : ObjectId( "4d9b642b832a4c4fb2000000" ),
"acted_at" : Date( 1302014955933 ),
"created_at" : Date( 1302014955933 ),
"updated_at" : Date( 1302014955933 ),
"_platform_id" : 3,
"guid" : 72106535190265857 }
Run Code Online (Sandbox Code Playgroud)
我相信的是Mongo Extended JSON.
当我读到这样一行并做:
json_line = json.dumps(line)
Run Code Online (Sandbox Code Playgroud)
我明白了:
"{ \"_id\" : ObjectId( \"4d9b642b832a4c4fb2000000\" ),
\"acted_at\" : Date( 1302014955933 ),
\"created_at\" : Date( 1302014955933 ),
\"updated_at\" : Date( 1302014955933 ),
\"_platform_id\" : 3,
\"guid\" : 72106535190265857 }\n"
Run Code Online (Sandbox Code Playgroud)
哪个还是<type 'str'>.
我也试过了
json_line = json.dumps(line, default=json_util.default)
Run Code Online (Sandbox Code Playgroud)
(请参阅pymongo json_util - 垃圾邮件检测阻止第三个链接)这似乎与上面的转储输出相同.加载给出错误:
json_line = json.loads(line, object_hook=json_util.object_hook)
ValueError: No JSON object could be decoded
Run Code Online (Sandbox Code Playgroud)
那么,我怎样才能将TenGen JSON的字符串转换为可解析的JSON?(最终目标是将制表符分隔数据流式传输到另一个数据库)
Fab*_*olm 15
你所拥有的是在TenGen模式下的Mongo Extended JSON转储(见这里).一些可能的方法:
如果可以再次转储,请通过MongoDB REST API使用严格输出模式.这应该给你真正的JSON而不是你现在拥有的.
使用bson从http://pypi.python.org/pypi/bson/读你已经有了BSON到Python的数据结构,然后你需要在这些任何处理(可能输出JSON).
使用MongoDB Python绑定连接到数据库以将数据导入Python,然后执行您需要的任何处理.(如果需要,您可以设置本地MongoDB实例并将转储的文件导入到该实例中.)
将Mongo Extended JSON从TenGen模式转换为Strict模式.您可以开发一个单独的过滤器来执行此操作(从stdin读取,使用Strict结构替换TenGen结构,并在stdout上输出结果),或者您可以在处理输入时执行此操作.
这是使用Python和正则表达式的示例:
import json, re
from bson import json_util
with open("data.tengenjson", "rb") as f:
# read the entire input; in a real application,
# you would want to read a chunk at a time
bsondata = f.read()
# convert the TenGen JSON to Strict JSON
# here, I just convert the ObjectId and Date structures,
# but it's easy to extend to cover all structures listed at
# http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON
jsondata = re.sub(r'ObjectId\s*\(\s*\"(\S+)\"\s*\)',
r'{"$oid": "\1"}',
bsondata)
jsondata = re.sub(r'Date\s*\(\s*(\S+)\s*\)',
r'{"$date": \1}',
jsondata)
# now we can parse this as JSON, and use MongoDB's object_hook
# function to get rich Python data structures inside a dictionary
data = json.loads(jsondata, object_hook=json_util.object_hook)
# just print the output for demonstration, along with the type
print(data)
print(type(data))
# serialise to JSON and print
print(json_util.dumps(data))
Run Code Online (Sandbox Code Playgroud)
根据您的目标,其中一个应该是一个合理的起点.
将整个bson文档加载到python内存中是很昂贵的.
如果要将其流式传输而不是加载整个文件并进行全部加载,则可以尝试使用此库.
https://github.com/bauman/python-bson-streaming
from bsonstream import KeyValueBSONInput
from sys import argv
for file in argv[1:]:
f = open(file, 'rb')
stream = KeyValueBSONInput(fh=f, fast_string_prematch="somthing") #remove fast string match if not needed
for id, dict_data in stream:
if id:
...process dict_data...
Run Code Online (Sandbox Code Playgroud)
小智 6
你可以像这样转换bson文件的行:
>>> import bson
>>> bs = open('file.bson', 'rb').read()
>>> for valid_dict in bson.decode_all( bs ):
....
Run Code Online (Sandbox Code Playgroud)
每个valid_dict元素都是一个有效的python dict,可以转换为json.
| 归档时间: |
|
| 查看次数: |
17957 次 |
| 最近记录: |