1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Python] Python 3.10+: call async function within a property in a way that does not produce...

Discussão em 'Python' iniciado por Stack, Outubro 5, 2024 às 22:52.

  1. Stack

    Stack Membro Participativo

    I have built a library that includes an ORM with the following use pattern:

    class Model(SqlModel):
    columns = ('id', 'details', 'parent_id')
    parent: RelatedModel

    Model.parent = belongs_to(Model, Model, 'parent_id')
    ...
    def example(some_id, some_other_id):
    record = Model.find(some_id)
    record.parent = Model.find(some_other_id)
    record.parent().save()


    The most recent improvement is that related models accessed through the property are loaded on the first read of the property to avoid making library users write model.parent().reload() before the property is first accessed. E.g. parent_details = Model.find(some_id).parent.details.

    An example implementation within a synchronous relation can be found here.

    I replicated the whole SQL model, query builder, and ORM to use async. An example implementation within an asynchronous relation can be found here. The async use pattern is similar to the synchronous one:

    class Model(AsyncSqlModel):
    columns = ('id', 'details', 'parent_id')
    parent: AsyncRelatedModel

    Model.parent = async_belongs_to(Model, Model, 'parent_id')
    ...
    async def example(some_id, some_other_id):
    record = await Model.find(some_id)
    record.parent = await Model.find(some_other_id)
    await record.parent().save()


    Reading the property within an async function (e.g. parent_details = (await Model.find(some_id)).parent.details) results in RuntimeError: asyncio.run() cannot be called from a running event loop. I tried fixing this by replacing asyncio.run with asyncio.get_running_loop().run_until_complete, but it results in RuntimeError: This event loop is already running. I attempted running it in a new loop, but that results in RuntimeError: Cannot run the event loop while another loop is running. Using the nest-asyncio package removed the RuntimeError but resulted in a ResourceWarning for an unclosed event loop, and the package repo was archived, so I need a better solution.

    The advice from a similar question is to rewrite the function to be async, but this is not a plausible solution for a property.

    Is there a solution that does not involve re-engineering the entire library use pattern or depending on an abandoned package?

    Continue reading...

Compartilhe esta Página