1

我有一个基于异步 Tornado 和 mongoDB 的 API。它工作正常,除了一个处理程序:

@gen.coroutine
def get(self, *args, **kwargs):
    """
    Gets tracking lib
    """
    data = self._get_request_data()
    self._serialize_request_data(AuthValidator, data)

    tags = yield self.motor.tags.find_one({"client_id": data["client_id"]})
    raise Return(self.write(tags))

当请求到来时,tornado 返回 HTTP 500 并带有以下堆栈跟踪:

response: Traceback (most recent call last):
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/web.py", line 1334, in _execute
result = yield result
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/gen.py", line 617, in run
value = future.result()
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/concurrent.py", line 109, in result
raise_exc_info(self._exc_info)
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/gen.py", line 620, in run
yielded = self.gen.throw(*sys.exc_info())
  File "/Users/artemkorhov/Projects/cartreminder/cartreminder_app/tracking_api/api_handlers/endpoints.py", line 35, in get
tags = yield self.motor.tags.find_one({"client_id": data["client_id"]})
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/gen.py", line 617, in run
value = future.result()
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/tornado/concurrent.py", line 109, in result
raise_exc_info(self._exc_info)
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/motor/__init__.py", line 676, in call_method
result = sync_method(self.delegate, *args, **kwargs)
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/pymongo/collection.py", line 721, in find_one
for result in cursor.limit(-1):
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/pymongo/cursor.py", line 1038, in next
if len(self.__data) or self._refresh():
  File "/Users/artemkorhov/Projects/cartreminder/env/lib/python2.7/site-packages/pymongo/cursor.py", line 982, in _refresh
self.__uuid_subtype))
RuntimeError: maximum recursion depth exceeded while encoding an object to BSON 

在 mongoDB“标签”集合中,我有(例如):

{
"_id" : ObjectId("540eec8227c565f77d4dcd23"),
"client_id" : "1111",
"tags" : {
    "cart_add" : [
        {
            "action_element" : "#addbutton1",
            "info_element" : "#product_element1"
        }
    ],
    "cart_delete" : [
        {
            "action_element" : "#deleteButton1",
            "info_element" : "#product_element1"
        }
    ],
    "email_known" : {
        "info_element" : ".tag1"
    },
    "order_complete" : {
        "action_element" : "#order_button1",
        "info_element" : {
            "product_wrap" : ".product_wrap",
            "product_id" : ".product_id_element",
            "quantity" : ".product_quantity_element",
            "price" : ".product_price_element"
        }
    }
}
}

有趣的部分是相同的“查找”方法在其他处理程序中完美运行,构建几乎相同

4

1 回答 1

5

您的“数据”字典具有循环引用,因此当 Motor 将“数据”传递给 PyMongo 以编码为 BSON 并发送到服务器时,BSON 编码器会递归超过 1000 次。我可以像这样重现此错误消息:

>>> import bson
>>> d = {}
>>> d['key'] = d  # Circular reference!
>>> bson.BSON.encode(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/emptysquare/.virtualenvs/motor/lib/python2.7/site-packages/bson/__init__.py", line 590, in encode
    return cls(_dict_to_bson(document, check_keys, uuid_subtype))
RuntimeError: maximum recursion depth exceeded while encoding an object to BSON

尝试对“数据”执行“pprint.pprint”以查看自引用发生的位置:

>>> import pprint
>>> pprint.pprint(d)
{'key': <Recursion on dict with id=140199700593680>}
于 2014-09-09T15:32:49.210 回答