插入pymongo集合时,'str'对象不支持项目赋值

时间:2014-12-30 14:11:13

标签: python mongodb pymongo

RHEL 6.5,python 2.6.6

我试图将已解码的消息写入MongoDB集合。 "已解码的消息"以字典的形式收到。在该字典中,键是所有字符串,值可以是字符串,整数,datetime.timedatetime.datetimeDecimal类型。

我已经编写了一个on_message函数,该函数使用参数context调用,该字符包含要保存到MongoDB的字典。我还写了一个lambda来转换一些不是JSON序列化的类型。

dthandler = lambda obj: (
    str(obj) 
    if isinstance(obj, Decimal)
    or isinstance(obj, datetime.time)
    else None
)

class Decoder(decoder.base.Base):

  # ...

  def on_message(self, context, payload):

    """  Write decoded message to DB
    """
    msg = dict(context)
    try:

        print self.mongo_coll

        # This is just a test to confirm the connection is established properly.
        # I am able to see this value in the DB using Robomongo after this insert 
        # call
        self.mongo_coll.insert({'foo': 'john'})

        x = json.dumps(context, default=dthandler)
        print x
        self.mongo_coll.insert(x)
    except errors.OperationFailure as op:
        print "Operation Exception"

    except Exception as ex:
        print "Serialization Exception (mongo/write.py)"
        exs = str(ex)
        print exs

        print '^^^^^'

print self.mongo_coll的调用产生:

  

收藏(数据库(MongoClient(' localhost',27017),u' itch'),   U'测试&#39)

print x的调用产生(所有结果都相似):

  

{" msg-type-name":" AddOrderAttributed"," next-expect-msg-seq-num":   3023982," mold-num-msgs":34," recv-timestamp":null," ord-ref-num":   4365786," msg-type":" F"," recv-time-nano":2523000," raw-price":   781200," msg-seq-num":3023981," shares":100," buy-sell":" B",   " stock":" RNR","归因":" RBCM","时间戳":" 09 :30:00.002189&#34 ;,   "价格":" 78.12"," tracking-number":1," recv-time-sec":1419431400,   " msg-size":40," mold-seq-num":3023959," stock-locate":6281,   "模具会议":" 000006896B"," msg-payload":" 00 28 46 18 89 00 01 1f   1a ce fb 57 59 00 00 00 00 00 42 9d da 42 00 00 00 64 52 4e 52 20 20   20 20 20 00 0b eb 90 52 42"}

然而,对self.mongo_coll.insert(x)的调用会产生Exception

  

序列化异常(mongo / write.py)

     

' STR'对象不支持项目分配

     

^^^^^

我很困惑,特别是考虑到我的代码中没有提及str,除了我的异常处理程序和dthandler内。

我做错了什么?


根据编辑和答案,我做了一些修改。唉,我还有麻烦。这是新代码:

 def on_message(self, context, payload):
    """  Write decoded message to DB
    """
    msg = dict(context)
    try:
        print self.mongo_coll
        self.mongo_coll.insert(msg)
        x = json.dumps(context, default=dthandler)
        print self.mongo_coll
        print x
        self.mongo_coll.insert(msg)
    except errors.OperationFailure as op:
        print "Operation Exception"
    except Exception as ex:
        traceback.print_exc()
        print "Serialization Exception (mongo/write.py)"
        exs = str(ex)
        print exs

        print '^^^^^'

...和输出:

Collection(Database(MongoClient('localhost', 27017), u'itch'), u'test')
Traceback (most recent call last):
  File "./decoder/mongo/write.py", line 69, in on_message
    self.mongo_coll.insert(msg)
  File "/usr/lib64/python2.6/site-packages/pymongo/collection.py", line 409, in insert
    gen(), check_keys, self.uuid_subtype, client)
InvalidDocument: Cannot encode object: Decimal('65.1')
Serialization Exception (mongo/write.py)
Cannot encode object: Decimal('65.1')
^^^^^

3 个答案:

答案 0 :(得分:2)

你的行

x = json.dumps(context, default=dthandler)

使x成为一个字符串。只需使用

self.mongo_coll.insert(msg)

最好不要直接插入context,而是插入msgdict,而不是上下文对象)。

答案 1 :(得分:1)

我无法判断这是否已经解决。但我遇到了同样的问题,所以我会在这里发布我的解决方案以帮助其他人。

我正在this example工作。

问题代码:

# insert the student object into MongoDB
object_id = student_collection.insert(a_student.to_JSON())

<强>解决方案:

object_id = student_collection.insert({"email": "daniel@mongocourse.com", "name": {"first": "Daniel", "last": "Watrous"}, "major": "Electrical Engineering"})

即使我们说&#34; to_JSON()&#34;在这里,insert方法变得混乱,并在执行时抛出错误。因为它得到一个字符串,它认为它是一个字符串,而不是JSON。

我使用的是Python 3.5。该版本也可能与它有关。也许它适用于Python 2.7。

希望这会对某人有所帮助。

答案 2 :(得分:0)

我遇到了与您相同的问题,并且找到了以下解决方案:

import json    

valuestr = json.dumps(myclass, default=lambda x:x.__dict__)
value = json.loads(valuestr) # <-- returned data is not string
db.posts.insert(value)