mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-07 21:00:33 +03:00
Added register_default_json() function
Register a typecaster for PostgreSQL 9.2 json.
This commit is contained in:
parent
26d71b4cba
commit
d963b478e2
|
@ -155,6 +155,8 @@ versions the `simplejson`_ module is be used if available. Note that the last
|
||||||
|
|
||||||
.. autofunction:: register_json
|
.. autofunction:: register_json
|
||||||
|
|
||||||
|
.. autofunction:: register_default_json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _adapt-hstore:
|
.. _adapt-hstore:
|
||||||
|
|
21
lib/_json.py
21
lib/_json.py
|
@ -43,6 +43,10 @@ else:
|
||||||
json = None
|
json = None
|
||||||
|
|
||||||
|
|
||||||
|
# oids from PostgreSQL 9.2
|
||||||
|
JSON_OID = 114
|
||||||
|
JSONARRAY_OID = 199
|
||||||
|
|
||||||
class Json(object):
|
class Json(object):
|
||||||
"""A wrapper to adapt a Python object to :sql:`json` data type.
|
"""A wrapper to adapt a Python object to :sql:`json` data type.
|
||||||
|
|
||||||
|
@ -130,7 +134,7 @@ def register_json(conn_or_curs=None, globally=False, loads=None,
|
||||||
if oid is None:
|
if oid is None:
|
||||||
oid, array_oid = _get_json_oids(conn_or_curs)
|
oid, array_oid = _get_json_oids(conn_or_curs)
|
||||||
|
|
||||||
JSON, JSONARRAY = create_json_typecasters(oid, array_oid, loads)
|
JSON, JSONARRAY = _create_json_typecasters(oid, array_oid, loads)
|
||||||
|
|
||||||
register_type(JSON, not globally and conn_or_curs or None)
|
register_type(JSON, not globally and conn_or_curs or None)
|
||||||
|
|
||||||
|
@ -139,7 +143,20 @@ def register_json(conn_or_curs=None, globally=False, loads=None,
|
||||||
|
|
||||||
return JSON, JSONARRAY
|
return JSON, JSONARRAY
|
||||||
|
|
||||||
def create_json_typecasters(oid, array_oid, loads=None):
|
def register_default_json(conn_or_curs=None, globally=False, loads=None):
|
||||||
|
"""
|
||||||
|
Create and register :sql:`json` typecasters for PostgreSQL 9.2 and following.
|
||||||
|
|
||||||
|
Since PostgreSQL 9.2 :sql:`json` is a builtin type, hence its oid is known
|
||||||
|
and fixed. This function allows specifying a customized *loads* function
|
||||||
|
for the default :sql:`json` type without querying the database.
|
||||||
|
All the parameters have the same meaning of `register_json()`.
|
||||||
|
"""
|
||||||
|
return register_json(conn_or_curs=conn_or_curs, globally=globally,
|
||||||
|
loads=loads, oid=JSON_OID, array_oid=JSONARRAY_OID)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_json_typecasters(oid, array_oid, loads=None):
|
||||||
"""Create typecasters for json data type."""
|
"""Create typecasters for json data type."""
|
||||||
if loads is None:
|
if loads is None:
|
||||||
if json is None:
|
if json is None:
|
||||||
|
|
|
@ -151,17 +151,14 @@ class NoneAdapter(object):
|
||||||
|
|
||||||
|
|
||||||
# Create default json typecasters for PostgreSQL 9.2 oids
|
# Create default json typecasters for PostgreSQL 9.2 oids
|
||||||
from psycopg2._json import create_json_typecasters
|
from psycopg2._json import register_default_json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
JSON, JSONARRAY = create_json_typecasters(114, 199)
|
JSON, JSONARRAY = register_default_json()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
|
||||||
register_type(JSON)
|
|
||||||
register_type(JSONARRAY)
|
|
||||||
|
|
||||||
del create_json_typecasters
|
del register_default_json
|
||||||
|
|
||||||
|
|
||||||
# Add the "cleaned" version of the encodings to the key.
|
# Add the "cleaned" version of the encodings to the key.
|
||||||
|
|
|
@ -970,7 +970,7 @@ def register_composite(name, conn_or_curs, globally=False):
|
||||||
|
|
||||||
|
|
||||||
# expose the json adaptation stuff into the module
|
# expose the json adaptation stuff into the module
|
||||||
from psycopg2._json import json, Json, register_json
|
from psycopg2._json import json, Json, register_json, register_default_json
|
||||||
|
|
||||||
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
|
||||||
|
|
||||||
|
|
|
@ -950,6 +950,24 @@ class JsonTestCase(unittest.TestCase):
|
||||||
if olda:
|
if olda:
|
||||||
psycopg2.extensions.register_type(olda)
|
psycopg2.extensions.register_type(olda)
|
||||||
|
|
||||||
|
@skip_if_no_json_module
|
||||||
|
@skip_before_postgres(9, 2)
|
||||||
|
def test_register_default(self):
|
||||||
|
curs = self.conn.cursor()
|
||||||
|
|
||||||
|
loads = lambda x: psycopg2.extras.json.loads(x, parse_float=Decimal)
|
||||||
|
psycopg2.extras.register_default_json(curs, loads=loads)
|
||||||
|
|
||||||
|
curs.execute("""select '{"a": 100.0, "b": null}'::json""")
|
||||||
|
data = curs.fetchone()[0]
|
||||||
|
self.assert_(isinstance(data['a'], Decimal))
|
||||||
|
self.assertEqual(data['a'], Decimal('100.0'))
|
||||||
|
|
||||||
|
curs.execute("""select array['{"a": 100.0, "b": null}']::json[]""")
|
||||||
|
data = curs.fetchone()[0]
|
||||||
|
self.assert_(isinstance(data[0]['a'], Decimal))
|
||||||
|
self.assertEqual(data[0]['a'], Decimal('100.0'))
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user