piccolo
piccolo copied to clipboard
InterfaceError- cannot perform operation: another operation is in progress
I get InterfaceError when execute get_or_create()
Models.objects().get_or_create(
where=(........),
defaults={
...............
},
).run_sync(in_pool=False)
Logs:
Traceback (most recent call last):
File "/home/-services/__pypackages__/3.10/lib/piccolo/engine/postgres.py", line 403, in _run_in_pool
response = await connection.fetch(query, *args)
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 620, in fetch
return await self._execute(
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 1658, in _execute
result, _ = await self.__execute(
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 1683, in __execute
return await self._do_execute(
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 1710, in _do_execute
stmt = await self._get_statement(
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 397, in _get_statement
statement = await self._protocol.prepare(
File "asyncpg/protocol/protocol.pyx", line 168, in prepare
RuntimeError: Task <Task pending name='Task-33' coro=<GetOrCreate.run() running at /home/-services/__pypackages__/3.10/lib/piccolo/query/methods/objects.py:58> cb=[_run_until_complete_cb() at /usr/local/lib/python3.10/asyncio/base_events.py:184]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop
During handling of the above exception, another exception occurred:
.
.
.
instance = await self.query.get(self.where).run(
File "/home/-services/__pypackages__/3.10/lib/piccolo/query/proxy.py", line 28, in run
return await self.query.run(node=node, in_pool=in_pool)
File "/home/-services/__pypackages__/3.10/lib/piccolo/query/methods/objects.py", line 121, in run
objects = await self.query.run(
File "/home/-services/__pypackages__/3.10/lib/piccolo/query/methods/objects.py", line 350, in run
results = await super().run(node=node, in_pool=in_pool)
File "/home/-services/__pypackages__/3.10/lib/piccolo/query/base.py", line 197, in run
return await self._run(node=node, in_pool=in_pool)
File "/home/-services/__pypackages__/3.10/lib/piccolo/query/base.py", line 179, in _run
results = await engine.run_querystring(
File "/home/-services/__pypackages__/3.10/lib/piccolo/engine/postgres.py", line 440, in run_querystring
return await self._run_in_pool(query, query_args)
File "/home/-services/__pypackages__/3.10/lib/piccolo/engine/postgres.py", line 402, in _run_in_pool
async with self.pool.acquire() as connection:
File "/home/-services/__pypackages__/3.10/lib/asyncpg/pool.py", line 220, in release
raise ex
File "/home/-services/__pypackages__/3.10/lib/asyncpg/pool.py", line 210, in release
await self._con.reset(timeout=budget)
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 1366, in reset
await self.execute(reset_query, timeout=timeout)
File "/home/-services/__pypackages__/3.10/lib/asyncpg/connection.py", line 317, in execute
return await self._protocol.query(query, timeout)
File "asyncpg/protocol/protocol.pyx", line 323, in query
File "asyncpg/protocol/protocol.pyx", line 707, in asyncpg.protocol.protocol.BaseProtocol._check_state
asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress
I execute some queries in run_sync() before executing get_or_create in run_sync command in the same flow.
When I pass get_or_create.....run_sync(in_pool=False) in the same flow, it works. What is the proper way to fix the issue?
So you've got something like this?
def my_function():
some_query.run_sync()
some_query.run_sync()
MyTable.objects().get_or_create(MyTable.my_column == "foo").run_sync()
You might be better off just making the function async:
async def my_function():
await some_query
await some_query
await MyTable.objects().get_or_create(MyTable.my_column == "foo")
>>> from piccolo.utils.sync import run_sync
>>> run_sync(my_function())
The error was probably happening because the sync code is using a shared connection pool, which can use some weirdness.