0

为了异步数据库访问,我正在尝试在我的 Tornado 应用程序中将 MongoEngine 与 MotorEngine 切换,但到目前为止我一无所获。

query

@gen.coroutine
    def get_all_users(self):
        users = yield User.objects.find_all()

handler

class IUser(BaseHandler):
    @asynchronous
    @gen.engine
    def get(self,userId=None, *args, **kwargs):
        try:
            userMethods = UserMethods()
            sessionId = self.request.headers.get('sessionId')
            ret = userMethods.get_all_users()
        except Exception as ex:
            print str(ex)

        self.finish()

当我打印ret变量时,它说<tornado.concurrent.Future object at 0x7fb0236fe450>. 如果我尝试打印ret.result()它会让我无处可去。

任何帮助表示赞赏,因为我正在努力解决我猜想的一切......

4

2 回答 2

2

get_all_users 需要以某种方式返回其值。在 Python 2.6 或 2.7 中,生成器不允许使用“return”语句,因此协程有一个特殊的“Return”异常:

@gen.coroutine
def get_all_users(self):
    users = yield User.objects.find_all()
    raise gen.Return(users)

在 Python 3.3 及更高版本中,您可以简单地“返回用户”。

现在在“get”中,调用“get_all_users”只会给你一个未决的未来,而不是一个值。您必须等待 Future 通过产生它来解析一个值:

ret = yield userMethods.get_all_users()

有关从协程调用协程的更多信息,请参阅我的“重构 Tornado 协程”

顺便说一句,你可以只用“gen.coroutine”来装饰“get”,它比“asynchronous”和“gen.engine”更现代,但任何一种风格都可以。

于 2014-09-23T12:54:51.027 回答
0

只是一个建议。如果你想避免每次使用它的方法时都创建一个 userMethods 实例:

userMethods = UserMethods()

您可以@classmethod在声明之前使用装饰器:

class UserMethods():
    pass

@classmethod
@tornado.gen.coroutine
def get_all_users(self):
    users = yield User.objects.find_all()
    raise gen.Return(users)

## class IUser
...

try:
    # userMethods = UserMethods()   --not necesary now--
    sessionId = self.request.headers.get('sessionId')
    ret = yield userMethods.get_all_users()
except Exception as ex:
    print str(ex)
...
于 2016-05-10T13:13:01.333 回答