mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +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