From: Damian Dimmich Date: Sat, 28 Jun 2014 18:47:20 +0000 (+0400) Subject: add has_key & contains operators for jsonb (ported over from hstore) X-Git-Tag: rel_1_0_0b1~349^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e5fcee975040d6d82baceb8e0535a548411faa6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git add has_key & contains operators for jsonb (ported over from hstore) --- diff --git a/lib/sqlalchemy/dialects/postgresql/json.py b/lib/sqlalchemy/dialects/postgresql/json.py index 37196dfb18..262ec20bd3 100644 --- a/lib/sqlalchemy/dialects/postgresql/json.py +++ b/lib/sqlalchemy/dialects/postgresql/json.py @@ -200,7 +200,7 @@ ischema_names['json'] = JSON -class JSONB(sqltypes.TypeEngine): +class JSONB(JSON): """Represent the Postgresql JSONB type. The :class:`.JSONB` type stores arbitrary JSONB format data, e.g.:: @@ -268,6 +268,7 @@ class JSONB(sqltypes.TypeEngine): """ __visit_name__ = 'JSONB' + hashable = False class comparator_factory(sqltypes.Concatenable.Comparator): """Define comparison operations for :class:`.JSON`.""" @@ -279,32 +280,27 @@ class JSONB(sqltypes.TypeEngine): def _adapt_expression(self, op, other_comparator): if isinstance(op, custom_op): + if op.opstring in ['?', '?&', '?|', '@>', '<@']: + return op, sqltypes.Boolean if op.opstring == '->': return op, sqltypes.Text return sqltypes.Concatenable.Comparator.\ _adapt_expression(self, op, other_comparator) - def bind_processor(self, dialect): - json_serializer = dialect._json_serializer or json.dumps - if util.py2k: - encoding = dialect.encoding - def process(value): - return json_serializer(value).encode(encoding) - else: - def process(value): - return json_serializer(value) - return process + def has_key(self, other): + """Boolean expression. Test for presence of a key. Note that the + key may be a SQLA expression. + """ + return self.expr.op('?')(other) + + def contains(self, other, **kwargs): + """Boolean expression. Test if keys (or array) are a superset of/contained + the keys of the argument jsonb expression. + """ + return self.expr.op('@>')(other) + + - def result_processor(self, dialect, coltype): - json_deserializer = dialect._json_deserializer or json.loads - if util.py2k: - encoding = dialect.encoding - def process(value): - return json_deserializer(value.decode(encoding)) - else: - def process(value): - return json_deserializer(value) - return process ischema_names['jsonb'] = JSONB \ No newline at end of file