MagicStack / asyncpg

A fast PostgreSQL Database Client Library for Python/asyncio.
Apache License 2.0
6.88k stars 399 forks source link

`asyncpg.connection.Connection.cursor()` does not support the `cursor_factory` keyword argument #991

Closed bamartin125 closed 1 year ago

bamartin125 commented 1 year ago

Honestly, I'm unsure if this should be a bug report or feature request as I am unaware of whether the lack of support for the cursor cursor_factory keyword was (un)intended.

The psycopg2 connection class's cursor() method has a signature that contains a cursor_factory keyword argument (see connection.cursor & connection-and-cursor-factories). The cursor_factory keyword argument is expected to be accepted for a portion of the internal psycopg2 implementation (see psycopg2/lib/extras.py#L773-L783).

One such case that the cursor_factory keyword is expected internally of psycopg2 is when calling psycopg2.extras.register_composite. Currently, when calling register_composite, psycopg2 chokes on the fact that asyncpg.connection.Connection.cursor does not accept the cursor_factory keyword.

Here is an example traceback snippet:

    psycopg2.extras.register_composite(
  File ".nox/test-3-8/lib/python3.8/site-packages/psycopg2/extras.py", line 1165, in register_composite
    caster = factory._from_db(name, conn_or_curs)
  File ".nox/test-3-8/lib/python3.8/site-packages/psycopg2/extras.py", line 1070, in _from_db
    conn, curs = _solve_conn_curs(conn_or_curs)
  File ".nox/test-3-8/lib/python3.8/site-packages/psycopg2/extras.py", line 783, in _solve_conn_curs
    curs = conn.cursor(cursor_factory=_cursor)
TypeError: cursor() got an unexpected keyword argument 'cursor_factory'

where the conn above is an asyncpg.connection.Connection.

I am very new to the asyncpg project and its internals. I also do not currently have the time to investigate this further, so I cannot currently comment on a path toward resolution. I'm hoping that someone else can comment or that I can come back soon to revisit this issue and further contribute to a solution. I don't know if it helps, but the aiopg project does document that it supports the cursor_factory keyword via aiopg.Connection.cursor.

bamartin125 commented 1 year ago

Looking at this again this morning, I think I am beginning to realize that asyncpg has no intention of integrating itself with nor aligning itself with psycopg or its APIs because they are in fact two separate projects implemented in quite different ways.

As I briefly learned about the use of this library within my project at work, I was somehow inclined to think that asyncpg was simply a compatibility layer built on top of psycopg for the asyncio usecase. This assumption was completely wrong. The "compatibility layer" design I describe does exist and one implementation of it is called aiopg. In my project (which uses sqlalchemy), I need to decide to do one of the following:

Closing this issue, though I hope this helps others that may fall into the same mindset/situation as I did.