Skip to content

lambda_stmt does not work with types created by TypeDecorator #9029

Closed
@Alexxxir

Description

@Alexxxir

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

Activity

added
bugSomething isn't working
and removed
requires triageNew issue that requires categorization
on Dec 27, 2022
added this to the 1.4.x milestone on Dec 27, 2022
zzzeek

zzzeek commented on Dec 27, 2022

@zzzeek
Member

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

from sqlalchemy import type_coerce
session.execute(
    select(Table).filter(lambda: Table.data == type_coerce(data, JSON))
)
sqla-tester

sqla-tester commented on Dec 27, 2022

@sqla-tester
Collaborator

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

sqla-tester commented on Dec 27, 2022

@sqla-tester
Collaborator

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

added
near-term releaseaddition to the milestone which indicates this should be in a near-term release
on Dec 27, 2022
added a commit that references this issue on Dec 27, 2022
4c80fad
added a commit that references this issue on Jun 9, 2025
502df8a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglambda sqlnear-term releaseaddition to the milestone which indicates this should be in a near-term release

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zzzeek@sqla-tester@Alexxxir

        Issue actions

          lambda_stmt does not work with types created by TypeDecorator · Issue #9029 · sqlalchemy/sqlalchemy