Open dgilman-hrp opened 1 month ago
asyncpg normally relies on duck typing when accepting inputs, e.g if an argument is an integer, asyncpg will happily accept an object that implements __int__()
, which is in line with Python's implicit casting tradition. Are you looking for a way to stringify objects specifically?
What I have is a class which inherits from Pydantic ConstrainedStr
. When I use it in a query, I get an error Expected unicode,
unless I explicitly cast it to str before passing it to the query.
Adding __str__
to the custom class does not solve the problem.
asyncpg/protocol/prepared_stmt.pyx:168:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
asyncpg/protocol/codecs/base.pyx:206: in asyncpg.protocol.protocol.Codec.encode
???
asyncpg/protocol/codecs/base.pyx:111: in asyncpg.protocol.protocol.Codec.encode_scalar
???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E TypeError: Expected unicode, got ApiKeyId
asyncpg/pgproto/./codecs/uuid.pyx:16: TypeError
It looks like the difference is that PyUnicode_AsUTF8AndSize
expects an actual str
whereas the equivalent file in psycopg2 works with custom types. https://github.com/psycopg/psycopg2/blob/a805acf59f402f554e95624b5e27518169ca7715/psycopg/adapter_qstring.c
Fixing this to work more like psycopg2 would fix my issue, as would a feature like register_adapter
In psycopg2,
register_adapter
along with utility functions provides a useful way to map custom Python classes into valid representations, often by relatively simple behaviors such as casting tostr
. There is no equivalent in asyncpg meaning moving from psycopg2 to asyncpg requires adding lots ofstr()
casts to add and select queries.The closest equivalent is
set_type_codec
but this only works for types that are registered with Postgres, not custom Python classes.