Using currval after insert_from with no inserted rows
Environment: PostgreSQL 9.6.6 aiopg 0.13.2 peewee 2.10.2 peewee-async 0.5.10 psycopg2 2.7.3.2
Assume we have the code like that
import asyncio
import peewee as pw
import peewee_async
db_name = # database name
db_conf = # conf
database = peewee_async.PooledPostgresqlDatabase(
db_name, **db_conf
)
class A(pw.Model):
name = pw.IntegerField(default=0)
class Meta:
db_table = "table_a"
database = database
class B(pw.Model):
name = pw.IntegerField(default=0)
class Meta:
db_table = "table_b"
database = database
A.create_table(True)
B.create_table(True)
objects = peewee_async.Manager(database)
objects.database.allow_sync = False
async def handler():
await objects.execute(B.insert_from([B.name], A.select(A.name)))
loop = asyncio.get_event_loop()
loop.run_until_complete(handler())
loop.close()
If we execute it we get an exception
Traceback (most recent call last):
File "rock.py", line 48, in <module>
loop.run_until_complete(handler())
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
return future.result()
File "rock.py", line 45, in handler
await objects.execute(B.insert_from([B.id], A.select(A.id)))
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/peewee_async.py", line 271, in execute
return (yield from execute(query))
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/peewee_async.py", line 435, in execute
return (yield from coroutine(query))
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/peewee_async.py", line 610, in insert
cursor, query.model_class)
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/peewee_async.py", line 1162, in last_insert_id_async
yield from cursor.execute("SELECT CURRVAL('%s\"%s\"')" % (schema, seq))
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/aiopg/cursor.py", line 114, in execute
yield from self._conn._poll(waiter, timeout)
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/aiopg/connection.py", line 238, in _poll
yield from asyncio.wait_for(self._waiter, timeout, loop=self._loop)
File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
return fut.result()
File "/home/yamitrofanov/.virtualenvs/peewee_async/local/lib/python3.6/site-packages/aiopg/connection.py", line 135, in _ready
state = self._conn.poll()
psycopg2.OperationalError: currval of sequence "table_b_id_seq" is not yet defined in this session
The last_insert_id_async uses CURRVAL.
The currval description says: Return the value most recently obtained by nextval for this sequence in the current session. (An error is reported if nextval has never been called for this sequence in this session.) Because this is returning a session-local value, it gives a predictable answer whether or not other sessions have executed nextval since the current session did.
In case above there are not rows in the table B(in general, if the query in insert_from does not return any rows). So there is nothing to insert that's why nextval has not been executed and the error occurred. I think this situation should be managed.
Same issue here :/
Could you try switching newer peewee / peewee-async? Probably this issue has been already solved there.