asyncpg is unable to resolve argument types for the following SQL query:
SELECT * FROM lorem WHERE (first_id, second_id) = $1
Complete example - this script fails:
import asyncio
import asyncpg
import os
async def main():
conn = await asyncpg.connect(os.environ['DATABASE_URL'])
try:
await conn.execute(
"""
create table "lorem" (
"first_id" int,
"second_id" int,
primary key ("first_id", "second_id")
);
"""
)
await conn.execute("insert into lorem values (5, 5)")
except asyncpg.DuplicateTableError:
pass
sql = "SELECT * FROM lorem WHERE (first_id) = $1"
print(sql)
print(await conn.fetch(sql, 5)) # Works
sql = "SELECT * FROM lorem WHERE (first_id, second_id) = $1"
print(sql)
print(await conn.fetch(sql, (5, 5))) # Crashes
asyncio.run(main())
with
SELECT * FROM lorem WHERE (first_id) = $1
[<Record first_id=5 second_id=5>]
SELECT * FROM lorem WHERE (first_id, second_id) = $1
Traceback (most recent call last):
File "nano.py", line 31, in <module>
asyncio.run(main())
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
return future.result()
File "nano.py", line 29, in main
print(await conn.fetch(sql, (5, 5))) # Crashes
File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 421, in fetch
return await self._execute(query, args, 0, timeout)
File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1414, in _execute
query, args, limit, timeout, return_status=return_status)
File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1422, in __execute
return await self._do_execute(query, executor, timeout)
File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1434, in _do_execute
stmt = await self._get_statement(query, None)
File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 356, in _get_statement
'in {} attempts'.format(tries)
asyncpg.exceptions._base.InternalClientError: could not resolve query result and/or argument types in 6 attempts
I haven't seen there any support of tuple unpacking. I'd separate parameters to $1 and $2 to avoid such problem
I haven't seen there any support of tuple unpacking. I'd separate parameters to
$1and$2to avoid such problem
Unfortunately, I can't do it - I'm using WHERE (first_id, second_id) = any($1) and providing a list of tuples.
This is a PostgreSQL protocol limitation. Anonymous row types (tuples) cannot be described. The error handling in this case could be better, sure.
@LEW21 If you can afford it, I would suggest declaring an explicit composite type:
CREATE TYPE id_pair AS (first_id int, second_id int)
and then
WHERE (first_id, second_id) = any($1::id_pair[])
Most helpful comment
This is a PostgreSQL protocol limitation. Anonymous row types (tuples) cannot be described. The error handling in this case could be better, sure.
@LEW21 If you can afford it, I would suggest declaring an explicit composite type:
CREATE TYPE id_pair AS (first_id int, second_id int)and then
WHERE (first_id, second_id) = any($1::id_pair[])