aio-libs / aiopg

aiopg is a library for accessing a PostgreSQL database from the asyncio
http://aiopg.readthedocs.io
BSD 2-Clause "Simplified" License
1.4k stars 160 forks source link

Incompatible with SQLAlchemy 1.4.38 and higher #890

Closed vladalexeev closed 2 years ago

vladalexeev commented 2 years ago

Describe the bug

In SQLAlchemy 1.4.38 they added optional parameter 'escape_names' to method 'constructparams' of TypeCompiler. Thus, it fails when executes a query with 'in' condition.

To Reproduce

Simply create a query like

table = Table(
    'my_table',
    metadata,
    Column("id", String),
    Column("name", String)
)

async with engine.acquire() as conn:
    await conn.execute(
        table.select().where(table.c.id.in_(["a", "b", "c"]))
    )

Expected behavior

Such kind of queries were executed successfully with previous versions of SQLAlchemy, but now it fails.

Logs/tracebacks

my_app/dao/dao.py:183: in get_list_by_filter
    async for row in conn.execute(query):
.venv/lib/python3.7/site-packages/aiopg/utils.py:115: in __anext__
    self._obj = await self._coro
.venv/lib/python3.7/site-packages/aiopg/sa/connection.py:123: in _execute
    compile_kwargs=self._query_compile_kwargs,
.venv/lib/python3.7/site-packages/sqlalchemy/sql/elements.py:501: in compile
    return self._compiler(dialect, **kw)
.venv/lib/python3.7/site-packages/sqlalchemy/sql/elements.py:565: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
.venv/lib/python3.7/site-packages/sqlalchemy/sql/compiler.py:800: in __init__
    self._process_parameters_for_postcompile(_populate_self=True)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <aiopg.sa.engine.APGCompiler_psycopg2 object at 0x7ef72e5b7400>
parameters = None, _populate_self = True
    def _process_parameters_for_postcompile(
        self, parameters=None, _populate_self=False
    ):
        """handle special post compile parameters.

        These include:

        * "expanding" parameters -typically IN tuples that are rendered
          on a per-parameter basis for an otherwise fixed SQL statement string.

        * literal_binds compiled with the literal_execute flag.  Used for
          things like SQL Server "TOP N" where the driver does not accommodate
          N as a bound parameter.

        """

        if parameters is None:
>           parameters = self.construct_params(escape_names=False)
E           TypeError: construct_params() got an unexpected keyword argument 'escape_names'
.venv/lib/python3.7/site-packages/sqlalchemy/sql/compiler.py:1143: TypeError

Python Version

$ python --version
Python 3.7.9

aiopg Version

$ python -m pip show aiopg
Name: aiopg
Version: 1.3.3
Summary: Postgres integration with asyncio.
Home-page: https://aiopg.readthedocs.io
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: BSD
Location: c:\python\python37\lib\site-packages
Requires: async-timeout, psycopg2-binary

OS

Windows, Linux

Additional context

No response

Code of Conduct

vladalexeev commented 2 years ago

As a minimal solution it's enough to add **kwargs to method construct_params of the class APGCompiler_psycopg2 in aiopg/sa/engine.py

class APGCompiler_psycopg2(PGCompiler_psycopg2):
    def construct_params(self, params=None, _group_number=None, _check=True, **kwargs):
        ...
Pliner commented 2 years ago

@vladalexeev Thanks for reporting the issue.

Could you please try https://pypi.org/project/aiopg/1.3.4b3/?

vladalexeev commented 2 years ago

@Pliner Yes, version 1.3.4b3 works correctly.

Pliner commented 2 years ago

@vladalexeev Thanks for confirming 👍🏻

@AVOstap Could you please also confirm that it works?

AVOstap commented 2 years ago

@Pliner yes, this version works correctly

Pliner commented 2 years ago

https://pypi.org/project/aiopg/1.3.4/

crky14 commented 1 year ago

@Pliner Hey, would it be possible to tag this to some minor/patch release ? We encountered this and currently patching it by ourself but would be great if it was functional by default. (1.4.x)