Asyncpg: Can't resolve tuple argument types

Created on 17 Sep 2019  路  3Comments  路  Source: MagicStack/asyncpg

  • asyncpg version: 0.18.3
  • PostgreSQL version: 11.5
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : No, it's on docker
  • Python version: 3.7.4
  • Platform: Linux
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: No
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : Didn't try uvloop.

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
question

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[])

All 3 comments

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 $1 and $2 to 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[])

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gitrus picture gitrus  路  5Comments

iomintz picture iomintz  路  7Comments

Artimi picture Artimi  路  7Comments

nhumrich picture nhumrich  路  8Comments

simplesteph picture simplesteph  路  4Comments