A
A
avigmati2016-02-22 13:33:44
MongoDB
avigmati, 2016-02-22 13:33:44

How to make asynchronous request to mongo using motor in __init__ class method?

There is this code:

def __init__(self):
        uri = 'mongodb://{}/{}'.format(kwargs['metrika_db_host'], kwargs['metrika_db_name'])
        client = motor.motor_tornado.MotorClient(uri)
        self.db = client.get_default_database()

        # падает с ошибкой TypeError: __init__() should return None, not 'generator'
        colls = yield self.db.collection_names()
        for c in colls:
            print('c: ', c)

My understanding is that the init method should return None and apparently colls = yield self.db.collection_names() returns a Future object which is a generator.
Nevertheless, I would like, for example, to create collections in __init__().
How to do this?
I tried to initiate in the __new__() method:
def __new__(cls, *args, **kwargs):
        print(cls, args, kwargs)
        uri = 'mongodb://{}/{}'.format(kwargs['metrika_db_host'], kwargs['metrika_db_name'])
        client = motor.motor_tornado.MotorClient(uri)
        print(client)
        cls.db = client.get_default_database()
        print(cls.db) # до этого момента все ок
        colls = yield cls.db.collection_names()  # зависает на этой строке
        for c in colls:
            print('c: ', c)
        return BaseCrawl.__new__(cls)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ilya, 2016-02-22
@avigmati

I had a somewhat similar question .
Methods like __init__ or __new__ are called as synchronous __within__ python, so there doesn't seem to be a pretty simple and pretty way to execute them asynchronously. Judging by the fact that there are special magic methods that can contain asynchronous code, asynchronous code in ordinary methods is not provided initially.
It's possible to initialize without async using something like asyncio.gather() or BaseEventLoop.run_until_complete(), but that's pointless because blocks other tasks.
I now, if necessary, make two initialization methods, __init__() in which everything that can be quickly done synchronously, and init() which is already asynchronous. Ugly,
but more obvious.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question