mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-10 19:16:34 +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_default_json
|
||||
|
||||
|
||||
|
||||
.. _adapt-hstore:
|
||||
|
|
21
lib/_json.py
21
lib/_json.py
|
@ -43,6 +43,10 @@ else:
|
|||
json = None
|
||||
|
||||
|
||||
# oids from PostgreSQL 9.2
|
||||
JSON_OID = 114
|
||||
JSONARRAY_OID = 199
|
||||
|
||||
class Json(object):
|
||||
"""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:
|
||||
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)
|
||||
|
||||
|
@ -139,7 +143,20 @@ def register_json(conn_or_curs=None, globally=False, loads=None,
|
|||
|
||||
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."""
|
||||
if loads is None:
|
||||
if json is None:
|
||||
|
|
|
@ -151,17 +151,14 @@ class NoneAdapter(object):
|
|||
|
||||
|
||||
# Create default json typecasters for PostgreSQL 9.2 oids
|
||||
from psycopg2._json import create_json_typecasters
|
||||
from psycopg2._json import register_default_json
|
||||
|
||||
try:
|
||||
JSON, JSONARRAY = create_json_typecasters(114, 199)
|
||||
JSON, JSONARRAY = register_default_json()
|
||||
except ImportError:
|
||||
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.
|
||||
|
|
|
@ -970,7 +970,7 @@ def register_composite(name, conn_or_curs, globally=False):
|
|||
|
||||
|
||||
# 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())
|
||||
|
||||
|
|
|
@ -950,6 +950,24 @@ class JsonTestCase(unittest.TestCase):
|
|||
if 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():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
|
Loading…
Reference in New Issue
Block a user