Как переместить запрос БД (который использует yield) в другую функцию?
Я играю с торнадо и mongodb, с асинхронным драйвером двигателя. При работе с обратными вызовами все нормально. Затем я обнаружил возможность использовать motor.Op или tornado.gen.Task для выполнения запроса только в одной функции:
Так что это работает:
class Contact_handler(Main_handler):
@web.asynchronous
@gen.coroutine
def get(self, other_id):
event = events.Event_send_contact_request(self.user_id)
result = yield motor.Op(db.users.update,
{'_id': ObjectId(other_id)},
{'$push': {'evts': event.data}}
)
self.finish("ok")
Но я бы хотел переместить этот запрос к базе данных в его собственную функцию в другой модуль. Проблема в том, что я не понимаю, как на самом деле работает доходность (несмотря на то, что я прочитал много вопросов о доходности). Так вот, что я пытался, но это не работает:
#------ file views.py -------------
class Contact_handler(Main_handler):
def get(self, other_id):
event = events.Event_send_contact_request(self.user_id)
result = model.push_event_to_user(other_id, event)
self.finish("ok")
И вызов в другой функции:
#------ file model.py -------------
@gen.coroutine
def push_event_to_user(user_id, event):
## Ajout de la demande dans les events du demandé:
yield motor.Op(db.users.update,
{'_id': ObjectId(user_id)},
{'$push': {'evts': event}}
)
Если я исследую с pdb:
(Pdb) l
157 event = events.Event_send_contact_request(self.user_id)
158 result = model.push_event_to_user(other_id, event)
159
160 import pdb; pdb.set_trace()
161
162 -> self.finish("ok")
163
(Pdb) result
<tornado.concurrent.TracebackFuture object at 0xa334b8c>
(Pdb) result.result()
*** Exception: DummyFuture does not support blocking for results
Любая помощь приветствуется, спасибо.
1 ответ
Я нашел другой способ сделать это, благодаря этому посту, который использует tornado.gen.Return. Мне все еще нужно уступить в моей основной функции, но сопрограмма проста.
Вот мой код сейчас:
#------ file views.py -------------
@web.asynchronous
@gen.coroutine
class Contact_handler(Main_handler):
def get(self, other_id):
event = events.Event_send_contact_request(self.user_id)
result = yield model.push_event_to_user(other_id, event)
self.finish("ok")
И вызов в другой функции:
#------ file model.py -------------
@gen.coroutine
def push_event_to_user(user_id, event):
## Ajout de la demande dans les events du demandé:
result = yield motor.Op(db.users.update,
{'_id': ObjectId(user_id)},
{'$push': {'evts': event}}
)
raise gen.Return(result)