On Feb 27, 2014, at 4:38 PM, Rob Crowell <[email protected]> wrote:
>
> # in_ clause with 1 STRING, 1 BINARY
> filter_cols = tuple_(HashTest.hash_val, HashTest.hash_type)
> filter_vals = ((encoded_hash, 'md5'),)
>
> q = session.query(HashTest)
> q = q.filter(filter_cols.in_((filter_vals)))
> ^
> HINT: No operator matches the given name and argument type(s). You might
> need to add explicit type casts.
> 'SELECT hashtest.hash_test.hash_val AS hashtest_hash_test_hash_val,
> hashtest.hash_test.hash_type AS hashtest_hash_test_hash_type,
> hashtest.hash_test.region AS hashtest_hash_test_region \nFROM
> hashtest.hash_test \nWHERE (hashtest.hash_test.hash_val,
> hashtest.hash_test.hash_type) IN ((%(param_1)s, %(param_2)s))' {'param_1':
> <psycopg2._psycopg.Binary object at 0x2d9d850>, 'param_2':
> <psycopg2._psycopg.Binary object at 0x2c18940>}
>
>
> It's complaining about an improper encoding for the BINARY column.
this has nothing to do with encoding and instead is about typing. you can see
in the output that SQLAlchemy is turning both elements of the IN tuple into a
Binary which would appear to be inappropriate here - the sqlalchemy.sql.Tuple
object isn’t yet smart enough to handle heterogeneous types. There’s a patch
which will resolve this attached to
https://bitbucket.org/zzzeek/sqlalchemy/issue/2977/tuple_-needs-to-record-heterogeneous-types
.
In the meantime you can actually lift and use that Tuple class that’s in the
patch:
from sqlalchemy.sql.expression import ClauseList, ColumnElement, \
_literal_as_binds, BindParameter
from sqlalchemy import types
class tuple_(ClauseList, ColumnElement):
def __init__(self, *clauses, **kw):
clauses = [_literal_as_binds(c) for c in clauses]
self.type = types.NULLTYPE
self._type_tuple = [arg.type for arg in clauses]
super(tuple_, self).__init__(*clauses, **kw)
@property
def _select_iterable(self):
return (self, )
def _bind_param(self, operator, obj):
return tuple_(*[
BindParameter(None, o, _compared_to_operator=operator,
_compared_to_type=type_, unique=True)
for o, type_ in zip(obj, self._type_tuple)
]).self_group()
signature.asc
Description: Message signed with OpenPGP using GPGMail
