-
Notifications
You must be signed in to change notification settings - Fork 729
Closed
Labels
Description
Hello! 👋 I am trying to use the latest app scheduler 4.x master branch with an async Postgres datastore.
I have a problem with releasing multiple schedules at the same time:
when the scheduler tries to release more than one value it fails with
sqlalchemy.exc.ResourceClosedError: This result object does not return rows. It has been closed automatically.
on the line
apscheduler/src/apscheduler/datastores/async_sqlalchemy.py
Lines 298 to 299 in 82992cd
if self._supports_update_returning: | |
update = update.returning(self.t_schedules.c.id) |
The problem occurs when the number of the items at update_args
is greater than 1, because sqlalchemy will use executemany under the hood
Suddenly, it is not possible to use asyncpg executemany
with returning statement
code to reproduce
import asyncio
from sqlalchemy import Integer, Column, bindparam, MetaData, String, Table
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.sql.elements import BindParameter
meta = MetaData()
t1 = Table("t1", meta, Column("id", Integer, primary_key=True), Column("name", String))
async def async_main():
engine = create_async_engine(
"postgresql+asyncpg://postgres:postgres@localhost/test", echo=True
)
async with engine.begin() as conn:
await conn.run_sync(meta.drop_all)
await conn.run_sync(meta.create_all)
await conn.execute(t1.insert(), [{"name": "name1"}, {"name": "name2"}])
p_id: BindParameter = bindparam("p_id")
p_name: BindParameter = bindparam("p_name")
stmt_args = [
{"p_id": 1, "p_name": f"name1_up"}, # works with only one item
{"p_id": 2, "p_name": f"name2_up"},
]
stmt = t1.update().where(t1.c.id == p_id).values(name=p_name).returning(t1.c.id)
result = await conn.execute(stmt, stmt_args)
print(list(result.scalars()))
asyncio.run(async_main())