diff options
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql')
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/base.py | 5 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/json.py | 33 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/psycopg2.py | 5 |
3 files changed, 28 insertions, 15 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index a7f838009..3edc28fed 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1439,9 +1439,12 @@ class PGDialect(default.DefaultDialect): _backslash_escapes = True - def __init__(self, isolation_level=None, **kwargs): + def __init__(self, isolation_level=None, json_serializer=None, + json_deserializer=None, **kwargs): default.DefaultDialect.__init__(self, **kwargs) self.isolation_level = isolation_level + self._json_deserializer = json_deserializer + self._json_serializer = json_serializer def initialize(self, connection): super(PGDialect, self).initialize(connection) 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 diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index ceb04b580..f5da8a711 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -428,6 +428,11 @@ class PGDialect_psycopg2(PGDialect): array_oid=array_oid) fns.append(on_connect) + if self.dbapi and self._json_deserializer: + def on_connect(conn): + extras.register_default_json(conn, loads=self._json_deserializer) + fns.append(on_connect) + if fns: def on_connect(conn): for fn in fns: |