2014-09-23 52 views
0

爲了實現異步數據庫訪問,我試圖在Tornado應用程序中將MotorEngine與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()它讓我無處可去。

因爲我的一切,我想掙扎任何幫助表示讚賞...

回答

2

GET_ALL_USERS需要以某種方式返回其值。在Python 2.6或2.7,發電機不允許使用「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() 

更多關於從協同程序調用協程,見我"Refactoring Tornado Coroutines"

順便說一句,你可以裝點「得」只有「gen.coroutine」,它比「異步」和「gen.engine」,但無論哪種風格的作品更加現代。

+0

A +答案,像往常一樣。謝謝。 – ivica 2014-09-23 13:27:54

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