Closed
Description
Describe the bug
Class TypeDecorator
has abstract method process_bind_param
that receive a bound parameter value to be converted. I expect that it should be called when I use lambda_stmt for parameters taken from the closure, but it doesn't seem to be happening for the filter method. This works for other methods and works when there is no lambda_stmt.
For example, I took JSONType from sqlalchemy_utils, because it's easy to understand
https://github.com/kvesteri/sqlalchemy-utils/blob/master/sqlalchemy_utils/types/json.py
To Reproduce
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, create_engine, select, lambda_stmt, update
from sqlalchemy.orm import Session
from sqlalchemy_utils import JSONType
Base = declarative_base()
class Table(Base):
__tablename__ = "table"
id = Column(Integer, primary_key=True)
data = Column(
JSONType(),
nullable=True,
)
engine = create_engine('sqlite:///sql.db', echo=True)
Base.metadata.create_all(engine)
session = Session(bind=engine)
data = {"aaaaa": "bbbbbb"}
session.execute(select(Table).filter(Table.data == data)) # no errors
session.execute(lambda_stmt(lambda: update(Table).filter(Table.id == 5).values(data=data))) # no errors
session.execute(lambda_stmt(lambda: select(Table).filter(Table.data == {"aaaaa": "bbbbbb"}))) # no errors
session.execute(lambda_stmt(lambda: select(Table).filter(Table.data == data))) # error
Error
File "/sqlalchemy_test.py", line 33, in <module>
session.execute(lambda_stmt(lambda: select(Table).filter(Table.data == data))) # error
File "/sqlalchemy/orm/session.py", line 1714, in execute
result = conn._execute_20(statement, params or {}, execution_options)
File "/sqlalchemy/engine/base.py", line 1705, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "/sqlalchemy/sql/lambdas.py", line 516, in _execute_on_connection
return connection._execute_clauseelement(
File "/sqlalchemy/engine/base.py", line 1572, in _execute_clauseelement
ret = self._execute_context(
File "/sqlalchemy/engine/base.py", line 1943, in _execute_context
self._handle_dbapi_exception(
File "/sqlalchemy/engine/base.py", line 2124, in _handle_dbapi_exception
util.raise_(
File "/sqlalchemy/util/compat.py", line 211, in raise_
raise exception
File "/sqlalchemy/engine/base.py", line 1900, in _execute_context
self.dialect.do_execute(
File "/sqlalchemy/engine/default.py", line 736, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 0 - probably unsupported type.
[SQL: SELECT "table".id, "table".data
FROM "table"
WHERE "table".data = ?]
[parameters: ({'aaaaa': 'bbbbbb'},)]
Versions
- OS: MacOS
- Python: 3.10
- SQLAlchemy: 1.4.45
- Database: sqlite
Additional context
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
zzzeek commentedon Dec 27, 2022
the expression relies upon the coerced type of the right side and there's no built-in coercion for a dictionary. not definite if this can be fixed yet.
type_coerce will allow the correct type to be picked up
sqla-tester commentedon Dec 27, 2022
Mike Bayer has proposed a fix for this issue in the main branch:
pass more contextual information to PyWrapper param create https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4327
sqla-tester commentedon Dec 27, 2022
Mike Bayer has proposed a fix for this issue in the rel_1_4 branch:
pass more contextual information to PyWrapper param create https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4328
pass more contextual information to PyWrapper param create
pass more contextual information to PyWrapper param create