that patch is in for 0.8 and 0.9. On Feb 27, 2014, at 7:29 PM, Michael Bayer <mike...@zzzcomputing.com> wrote:
> > On Feb 27, 2014, at 4:38 PM, Rob Crowell <rob.crow...@moat.com> 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