From fec03c88d659bf9a0b102dd328afac1ba3dc7f23 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 17 Dec 2013 17:46:09 -0500 Subject: - make the json serializer and deserializer per-dialect, so that we are compatible with psycopg2's per-connection/cursor approach. add round trip tests for both native and non-native. --- lib/sqlalchemy/dialects/postgresql/json.py | 33 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'lib/sqlalchemy/dialects/postgresql/json.py') diff --git a/lib/sqlalchemy/dialects/postgresql/json.py b/lib/sqlalchemy/dialects/postgresql/json.py index 5b8ad68f5..7ba8b1abe 100644 --- a/lib/sqlalchemy/dialects/postgresql/json.py +++ b/lib/sqlalchemy/dialects/postgresql/json.py @@ -56,22 +56,25 @@ class JSON(sqltypes.TypeEngine): will be detected by the unit of work. See the example at :class:`.HSTORE` for a simple example involving a dictionary. + Custom serializers and deserializers are specified at the dialect level, + that is using :func:`.create_engine`. The reason for this is that when + using psycopg2, the DBAPI only allows serializers at the per-cursor + or per-connection level. E.g.:: + + engine = create_engine("postgresql://scott:tiger@localhost/test", + json_serializer=my_serialize_fn, + json_deserializer=my_deserialize_fn + ) + + When using the psycopg2 dialect, the json_deserializer is registered + against the database using ``psycopg2.extras.register_default_json``. + .. versionadded:: 0.9 """ __visit_name__ = 'JSON' - def __init__(self, json_serializer=None, json_deserializer=None): - if json_serializer: - self.json_serializer = json_serializer - else: - self.json_serializer = json.dumps - if json_deserializer: - self.json_deserializer = json_deserializer - else: - self.json_deserializer = json.loads - class comparator_factory(sqltypes.Concatenable.Comparator): """Define comparison operations for :class:`.JSON`.""" @@ -113,23 +116,25 @@ class JSON(sqltypes.TypeEngine): _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 self.json_serializer(value).encode(encoding) + return json_serializer(value).encode(encoding) else: def process(value): - return self.json_serializer(value) + return json_serializer(value) return process def result_processor(self, dialect, coltype): + json_deserializer = dialect._json_deserializer or json.loads if util.py2k: encoding = dialect.encoding def process(value): - return self.json_deserializer(value.decode(encoding)) + return json_deserializer(value.decode(encoding)) else: def process(value): - return self.json_deserializer(value) + return json_deserializer(value) return process -- cgit v1.2.1