asyncpg icon indicating copy to clipboard operation
asyncpg copied to clipboard

Nested custom types in Postgres break `asyncpg.Record` subclassing

Open foxx opened this issue 3 years ago • 2 comments
trafficstars

  • asyncpg version: v0.25.0

  • PostgreSQL version: 14

  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce the issue with a local PostgreSQL install?: on-premise

  • Python version: 3.10.1

  • 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?: n/a

  • Can the issue be reproduced under both asyncio and uvloop?: n/a

It would appear that nested types are not converted to a user specified record_class, and instead will always use asyncpg.Record.

For example:


CREATE TYPE my_custom_type AS (
    id int,
    filename text,
    sql text
);

CREATE TABLE my_table (
    files my_custom_type[] NOT NULL,
);

SELECT * FROM my_table

If you specify a custom record_class, then the record from SELECT * FROM my_table will be your subclass. However, the value inside record['files'] will use the asyncpg.Record class, rather than the custom one specified.

What should actually happen?

I think if a user specifies a record_class, then this class should always be used, even for nested custom types. It's quite unexpected behaviour for asyncpg to use the default class when a custom one has been specified.

foxx avatar Feb 25 '22 19:02 foxx

Have you tried to set type codec via (connection)[https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.set_type_codec]?

Could you share relevant code snippet?

eirnym avatar Feb 26 '22 08:02 eirnym

https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.set_type_codec

Asyncpg does not support custom codecs for composite types:

async def set_type_codec(...):
    ...
    if not introspection.is_scalar_type(typeinfo):
        raise exceptions.InterfaceError(
            'cannot use custom codec on non-scalar type {}.{}'.format(schema, typename))

ponomar avatar May 17 '23 07:05 ponomar