asyncpg
asyncpg copied to clipboard
Nested custom types in Postgres break `asyncpg.Record` subclassing
-
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.
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?
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))