2012-08-08 21 views
16

तो मेरे पास एक मोंगो डीबी डंप से .bson की एक बड़ी मात्रा है। मैं कमांड लाइन पर bsondump का उपयोग कर रहा हूं, आउटपुट को पायदान के लिए stdin के रूप में पाइप कर रहा हूं। यह सफलतापूर्वक बीएसओएन से 'JSON' में परिवर्तित हो जाता है लेकिन वास्तव में यह एक स्ट्रिंग है, और प्रतीत होता है कि कानूनी JSON नहीं है।मैं मोंडो डीबी के बांडडम्प को जेएसओएन में बदलने के लिए पायथन का उपयोग कैसे कर सकता हूं?

उदाहरण के लिए एक इनकमिंग लाइन इस तरह दिखता है:

{ "_id" : ObjectId("4d9b642b832a4c4fb2000000"), 
    "acted_at" : Date(1302014955933), 
    "created_at" : Date(1302014955933), 
    "updated_at" : Date(1302014955933), 
    "_platform_id" : 3, 
    "guid" : 72106535190265857 } 

कौन सा मैं belive Mongo Extended JSON है।

जब मैं इस तरह के एक लाइन में पढ़ सकते हैं और कार्य करें:

json_line = json.dumps(line) 

मैं:

"{ \"_id\" : ObjectId(\"4d9b642b832a4c4fb2000000\"), 
\"acted_at\" : Date(1302014955933), 
\"created_at\" : Date(1302014955933), 
\"updated_at\" : Date(1302014955933), 
\"_platform_id\" : 3, 
\"guid\" : 72106535190265857 }\n" 

अब भी है कौन सा <type 'str'>। (देखें pymongo json_util - अनचाहा जाँच एक तिहाई लिंक को रोकती है)

मैं भी

json_line = json.dumps(line, default=json_util.default) 

की कोशिश की है कौन सा उत्पादन करने लगता है एक ही जैसा कि ऊपर उदासीनता। भार एक त्रुटि देता है:

json_line = json.loads(line, object_hook=json_util.object_hook) 
ValueError: No JSON object could be decoded 

तो, मैं टेनजेन JSON की स्ट्रिंग को दृष्टांत जेएसओएन में कैसे बदल सकता हूं? (अंतिम लक्ष्य टैब से अलग डेटा को किसी अन्य डेटाबेस में स्ट्रीम करना है)

+1

आप 'bson' को देखा है? http://pypi.python.org/pypi/bson/0.3.2 –

+0

क्या यह मोंगो निर्भरता को हटाने के अलावा कुछ और करता है? मुझे समझ में नहीं आता कि यह मेरा मुद्दा कैसे हो सकता है, लेकिन मैं इसे और अधिक देखूंगा। –

+0

संभावित डुप्लिकेट [JSON से PyMongo ऑब्जेक्ट आईडी को deserialize करने में असमर्थ] (http://stackoverflow.com/questions/8409194/unable-to-deserialize-pymongo-objectid-from-json) –

उत्तर

10

आपके पास क्या है जो टेन्गेन मोड में मोंगो विस्तारित JSON में डंप है (here देखें)। कुछ संभव तरीके जाना:

  1. आप फिर से डंप कर सकते हैं, MongoDB बाकी एपीआई के माध्यम से सख्त उत्पादन मोड का उपयोग करें। इससे आपको जो कुछ है उसके बदले आपको वास्तविक JSON देना चाहिए।

  2. उपयोग bsonhttp://pypi.python.org/pypi/bson/ से BSON अजगर डेटा संरचनाओं में आपके पास पहले से पढ़ने के लिए और उसके बाद जो कुछ भी प्रसंस्करण आप उन पर की जरूरत है (संभवतः JSON outputting) से करते हैं।

  3. पाइथन में डेटा प्राप्त करने के लिए डेटाबेस से कनेक्ट करने के लिए मोंगोडीबी पायथन बाइंडिंग का उपयोग करें, और उसके बाद आपको जो भी प्रोसेसिंग चाहिए, वह करें। (यदि आवश्यक हो, तो आप स्थानीय मोंगोडीबी इंस्टेंस स्थापित कर सकते हैं और उसमें अपनी डंप की गई फाइलों को आयात कर सकते हैं।)

  4. मोंगो विस्तारित JSON को TenGen मोड से सख्त मोड में कनवर्ट करें। आप इसे करने के लिए एक अलग फ़िल्टर विकसित कर सकते हैं (stdin से पढ़ें, सख्त संरचनाओं के साथ TenGen संरचनाओं को प्रतिस्थापित करें, और stdout पर परिणाम आउटपुट) या आप इनपुट को संसाधित करते समय ऐसा कर सकते हैं।

यहाँ एक उदाहरण पायथन और नियमित अभिव्यक्ति का उपयोग कर रहा है:

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)) 

अपने लक्ष्य पर निर्भर करता है, इनमें से किसी एक के लिए एक उचित शुरुआती बिंदु होना चाहिए।

+0

हां, मैंने अपने प्रश्न में उस विस्तारित JSON पृष्ठ से लिंक किया है। मैंने बीएसओएन पुस्तकालय की कोशिश की है और यह मेरा लक्ष्य पूरा नहीं किया है। bsondump एकमात्र चीज थी जिसे मैं काम करने के लिए मिल सकता था, लेकिन यह मुझे एक स्ट्रिंग दे रहा है। डेटा डंपिंग या पुनः लोड करना व्यवहार्य विकल्प नहीं हैं। –

+1

@ पीटर नचबौर: मैंने यह दिखाने के लिए एक विकल्प जोड़ा कि आप टेनजेन JSON प्रारूप को सख्त JSON में कैसे परिवर्तित कर सकते हैं। क्या आपके मन में यह और अधिक है? –

+0

मदद जारी रखने के लिए धन्यवाद :) अब भार काम करता है। अंत में मुझे लगता है कि आप json.dumps का मतलब नहीं है json_util.dumps (बाद में अस्तित्व में प्रतीत नहीं होता है) लेकिन यह काम नहीं करता है। हालांकि, मुझे यकीन नहीं है कि मुझे अब इसकी आवश्यकता है कि मेरे पास एक नियम है। चीयर्स! –

6

आप इस तरह bson फ़ाइल की तर्ज परिवर्तित कर सकते हैं:

>>> import bson 
>>> bs = open('file.bson', 'rb').read() 
>>> for valid_dict in bson.decode_all(bs): 
.... 

प्रत्येक valid_dict तत्व एक वैध अजगर dict कि आप json में बदल सकते हैं हो जाएगा।

+0

कि /__init__.py ", लाइन 473, decode_all अंत = लेन (डेटा) - 1 टाइप एरर: प्रकार 'फ़ाइल' की ऑब्जेक्ट में कोई लेन नहीं है() –

8

पाइथन मेमोरी में एक संपूर्ण बीएसओ दस्तावेज़ लोड करना महंगा है।

यदि आप पूरी फ़ाइल लोड करने और लोड करने के बजाय इसे स्ट्रीम करना चाहते हैं, तो आप इस लाइब्रेरी को आजमा सकते हैं।

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...