mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +03:00 
			
		
		
		
	Added hstore typecaster registration.
This commit is contained in:
		
							parent
							
								
									fef9727cce
								
							
						
					
					
						commit
						6d441b6e03
					
				| 
						 | 
					@ -567,5 +567,48 @@ class HstoreAdapter(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parse = classmethod(parse)
 | 
					    parse = classmethod(parse)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def register_hstore(conn_or_curs):
 | 
				
			||||||
 | 
					    """Register adapter/typecaster for dict/hstore reading/writing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The adapter must be registered on a connection or cursor as the hstore
 | 
				
			||||||
 | 
					    oid is different in every database.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Raise `~psycopg2.ProgrammingError` if hstore is not installed in the
 | 
				
			||||||
 | 
					    target database.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if hasattr(conn_or_curs, 'execute'):
 | 
				
			||||||
 | 
					        conn = conn_or_curs.connection
 | 
				
			||||||
 | 
					        curs = conn_or_curs
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        conn = conn_or_curs
 | 
				
			||||||
 | 
					        curs = conn_or_curs.cursor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Store the transaction status of the connection to revert it after use
 | 
				
			||||||
 | 
					    conn_status = conn.status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # get the oid for the hstore
 | 
				
			||||||
 | 
					    curs.execute("""\
 | 
				
			||||||
 | 
					SELECT t.oid, typarray
 | 
				
			||||||
 | 
					FROM pg_type t JOIN pg_namespace ns
 | 
				
			||||||
 | 
					    ON typnamespace = ns.oid
 | 
				
			||||||
 | 
					WHERE typname = 'hstore' and nspname = 'public';
 | 
				
			||||||
 | 
					""")
 | 
				
			||||||
 | 
					    oids = curs.fetchone()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # revert the status of the connection as before the command
 | 
				
			||||||
 | 
					    if (conn_status != _ext.STATUS_IN_TRANSACTION
 | 
				
			||||||
 | 
					    and conn.isolation_level != _ext.ISOLATION_LEVEL_AUTOCOMMIT):
 | 
				
			||||||
 | 
					        conn.rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if oids is None:
 | 
				
			||||||
 | 
					        raise psycopg2.ProgrammingError(
 | 
				
			||||||
 | 
					            "hstore type not found in the database. "
 | 
				
			||||||
 | 
					            "please install it from your 'contrib/hstore.sql' file")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # create and register the typecaster
 | 
				
			||||||
 | 
					    HSTORE = _ext.new_type((oids[0],), "HSTORE", HstoreAdapter.parse)
 | 
				
			||||||
 | 
					    _ext.register_type(HSTORE, conn_or_curs)
 | 
				
			||||||
 | 
					    _ext.register_adapter(dict, HstoreAdapter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
 | 
					__all__ = filter(lambda k: not k.startswith('_'), locals().keys())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,6 +186,29 @@ class HstoreTestCase(unittest.TestCase):
 | 
				
			||||||
        ko('"a=>"1"')
 | 
					        ko('"a=>"1"')
 | 
				
			||||||
        ko('"a"=>"1", "b"=>NUL')
 | 
					        ko('"a"=>"1", "b"=>NUL')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_register_conn(self):
 | 
				
			||||||
 | 
					        from psycopg2.extras import register_hstore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        register_hstore(self.conn)
 | 
				
			||||||
 | 
					        cur = self.conn.cursor()
 | 
				
			||||||
 | 
					        cur.execute("select null::hstore, ''::hstore, 'a => b'::hstore")
 | 
				
			||||||
 | 
					        t = cur.fetchone()
 | 
				
			||||||
 | 
					        self.assert_(t[0] is None)
 | 
				
			||||||
 | 
					        self.assertEqual(t[1], {})
 | 
				
			||||||
 | 
					        self.assertEqual(t[2], {'a': 'b'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_register_curs(self):
 | 
				
			||||||
 | 
					        from psycopg2.extras import register_hstore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cur = self.conn.cursor()
 | 
				
			||||||
 | 
					        register_hstore(cur)
 | 
				
			||||||
 | 
					        cur.execute("select null::hstore, ''::hstore, 'a => b'::hstore")
 | 
				
			||||||
 | 
					        t = cur.fetchone()
 | 
				
			||||||
 | 
					        self.assert_(t[0] is None)
 | 
				
			||||||
 | 
					        self.assertEqual(t[1], {})
 | 
				
			||||||
 | 
					        self.assertEqual(t[2], {'a': 'b'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_suite():
 | 
					def test_suite():
 | 
				
			||||||
    return unittest.TestLoader().loadTestsFromName(__name__)
 | 
					    return unittest.TestLoader().loadTestsFromName(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user