Получить результат из асинхронного запроса MotorEngine
Я пытаюсь переключить MongoEngine с MotorEngine в моем приложении Tornado ради асинхронного доступа к БД, и до сих пор я не получил ничего.
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, поэтому сопрограммы имеют специальное исключение "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()
Для получения дополнительной информации о вызове сопрограмм из сопрограмм см. Мой "Рефакторинг сопрограмм Торнадо".
Кстати, вы можете украсить "get" просто "gen.coroutine", он более современный, чем "asynchronous" и "gen.engine", но любой стиль работает.
Просто предложение. Если вы хотите избежать создания экземпляра 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)
...