diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-19 10:50:05 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-19 12:37:26 -0400 |
| commit | 807d4945d2c1e2f2e1c77ac9ee6e84af330706a3 (patch) | |
| tree | 4bb43a5fa68f8515eb965fc863e6bbbc21429d4f /lib/sqlalchemy/sql | |
| parent | 42c0928a731954649e95a7ee56b6709b1ec59aed (diff) | |
| download | sqlalchemy-807d4945d2c1e2f2e1c77ac9ee6e84af330706a3.tar.gz | |
check for TypeDecorator when handling getitem
Fixed issue where :class:`.TypeDecorator` would not correctly proxy the
``__getitem__()`` operator when decorating the :class:`.ARRAY` datatype,
without explicit workarounds.
Fixes: #7249
Change-Id: I3273572b4757e41fb5952639cb867314227d368a
Diffstat (limited to 'lib/sqlalchemy/sql')
| -rw-r--r-- | lib/sqlalchemy/sql/default_comparator.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/type_api.py | 23 |
2 files changed, 27 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/default_comparator.py b/lib/sqlalchemy/sql/default_comparator.py index 512fca8d0..619be2cd1 100644 --- a/lib/sqlalchemy/sql/default_comparator.py +++ b/lib/sqlalchemy/sql/default_comparator.py @@ -232,7 +232,11 @@ def _in_impl( def _getitem_impl( expr: ColumnElement[Any], op: OperatorType, other: Any, **kw: Any ) -> ColumnElement[Any]: - if isinstance(expr.type, type_api.INDEXABLE): + if ( + isinstance(expr.type, type_api.INDEXABLE) + or isinstance(expr.type, type_api.TypeDecorator) + and isinstance(expr.type.impl_instance, type_api.INDEXABLE) + ): other = coercions.expect( roles.BinaryElementRole, other, expr=expr, operator=op ) diff --git a/lib/sqlalchemy/sql/type_api.py b/lib/sqlalchemy/sql/type_api.py index efaf5d2a7..6c1a99daa 100644 --- a/lib/sqlalchemy/sql/type_api.py +++ b/lib/sqlalchemy/sql/type_api.py @@ -1551,8 +1551,11 @@ class TypeDecorator(SchemaEventTarget, ExternalType, TypeEngine[_T]): the default rules of :meth:`.TypeEngine.coerce_compared_value` should be used in order to deal with operators like index operations:: + from sqlalchemy import JSON + from sqlalchemy import TypeDecorator + class MyJsonType(TypeDecorator): - impl = postgresql.JSON + impl = JSON cache_ok = True @@ -1562,6 +1565,24 @@ class TypeDecorator(SchemaEventTarget, ExternalType, TypeEngine[_T]): Without the above step, index operations such as ``mycol['foo']`` will cause the index value ``'foo'`` to be JSON encoded. + Similarly, when working with the :class:`.ARRAY` datatype, the + type coercion for index operations (e.g. ``mycol[5]``) is also + handled by :meth:`.TypeDecorator.coerce_compared_value`, where + again a simple override is sufficient unless special rules are needed + for particular operators:: + + from sqlalchemy import ARRAY + from sqlalchemy import TypeDecorator + + class MyArrayType(TypeDecorator): + impl = ARRAY + + cache_ok = True + + def coerce_compared_value(self, op, value): + return self.impl.coerce_compared_value(op, value) + + """ __visit_name__ = "type_decorator" |
