为了异步数据库访问,我试图在我的Tornado应用程序中使用MotorEngine切换MongoEngine,到目前为止,我无处可去。
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()
,我就无处可去。
任何帮助都会受到赞赏,因为我正在努力解决一切......
答案 0 :(得分: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,而不是一个值。您必须等待Future通过产生它来解析为某个值:
ret = yield userMethods.get_all_users()
有关从协同程序调用协同程序的更多信息,请参阅我的"Refactoring Tornado Coroutines"。
顺便说一下,你可以用“gen.coroutine”装饰“get”,它比“异步”和“gen.engine”更现代,但两种风格都有效。
答案 1 :(得分: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)
...