Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add equivalent to psycopg2 register_adapter #1186

Open
dgilman-hrp opened this issue Oct 4, 2024 · 2 comments
Open

Add equivalent to psycopg2 register_adapter #1186

dgilman-hrp opened this issue Oct 4, 2024 · 2 comments

Comments

@dgilman-hrp
Copy link

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 to str. There is no equivalent in asyncpg meaning moving from psycopg2 to asyncpg requires adding lots of str() 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.

@dgilman-hrp dgilman-hrp changed the title Add equivalent to sycopg2 register_adapter Add equivalent to psycopg2 register_adapter Oct 4, 2024
@elprans
Copy link
Member

elprans commented Oct 18, 2024

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?

@dgilman-hrp
Copy link
Author

dgilman-hrp commented Oct 20, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants