mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +03:00 
			
		
		
		
	extensions.rst is shaping up!
This commit is contained in:
		
							parent
							
								
									4316ddf30a
								
							
						
					
					
						commit
						b97b0b04de
					
				| 
						 | 
					@ -1,3 +1,9 @@
 | 
				
			||||||
 | 
					2005-11-19  Federico Di Gregorio  <fog@initd.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* doc/extensions.rst: included Daniele's work after minor cosmetic changes
 | 
				
			||||||
 | 
						like using the new constants instead of numbers for transaction isolation
 | 
				
			||||||
 | 
						levels.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2005-11-17  Federico Di Gregorio  <fog@initd.org>
 | 
					2005-11-17  Federico Di Gregorio  <fog@initd.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* ZPsycopgDA/pool.py: fixed connections leak by using the new name
 | 
						* ZPsycopgDA/pool.py: fixed connections leak by using the new name
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,9 @@ rolling back a transaction will not be explained but just used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__ http://www.python.org/peps/pep-0249.html
 | 
					__ http://www.python.org/peps/pep-0249.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many objects and extension functions are defined in the `psycopg2.extensions`
 | 
				
			||||||
 | 
					module.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Connection and cursor factories
 | 
					Connection and cursor factories
 | 
				
			||||||
===============================
 | 
					===============================
 | 
				
			||||||
| 
						 | 
					@ -31,16 +34,157 @@ tzinfo factories
 | 
				
			||||||
Setting transaction isolation levels
 | 
					Setting transaction isolation levels
 | 
				
			||||||
====================================
 | 
					====================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					psycopg2 connection objects hold informations about the PostgreSQL `transaction
 | 
				
			||||||
 | 
					isolation level`_.  The current transaction level can be read from the
 | 
				
			||||||
 | 
					`connection.isolation_level` attribute.  The default isolation level is read
 | 
				
			||||||
 | 
					committed.  A different isolation level con be set through the
 | 
				
			||||||
 | 
					`connection.set_isolation_level()` method.  The method takes the new level as
 | 
				
			||||||
 | 
					parameter.  Isolation levels are defined in the `psycopg2.extensions` module:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ISOLATION_LEVEL_AUTOCOMMIT
 | 
				
			||||||
 | 
					    No transaction is started when command are issued and no
 | 
				
			||||||
 | 
					    `.commit()`/`.rollback()` is required.  Some PostgreSQL command such as
 | 
				
			||||||
 | 
					    ``CREATE DATABASE`` can't run into a transaction: to run such command use
 | 
				
			||||||
 | 
					    `.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)`.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					ISOLATION_LEVEL_READ_COMMITED
 | 
				
			||||||
 | 
					    This is the default value.  A new transaction is started at the first
 | 
				
			||||||
 | 
					    `.execute()` command on a cursor and at each new `.execute()` after a
 | 
				
			||||||
 | 
					    `.commit()` or a `.rollback()`.  The transaction runs in the PostgreSQL
 | 
				
			||||||
 | 
					    ``READ COMMITTED`` isolation level.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					ISOLATION_LEVEL_REPEATABLE_READ
 | 
				
			||||||
 | 
					    Same as ISOLATION_LEVEL_SERIALIZABLE: PostgreSQL treats the SQL
 | 
				
			||||||
 | 
					    ``REPEATABLE READ`` isolation level as ``SERIALIZABLE``.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					ISOLATION_LEVEL_SERIALIZABLE
 | 
				
			||||||
 | 
					    Serializable. Transactions are run at a ``SERIALIZABLE`` isolation level.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _transaction isolation level: 
 | 
				
			||||||
 | 
					   http://www.postgresql.org/docs/8.1/static/transaction-iso.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Adaptation of Python values to SQL types
 | 
					Adaptation of Python values to SQL types
 | 
				
			||||||
========================================
 | 
					========================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					psycopg2 casts Python variables to SQL literals by type.  Standard Python types
 | 
				
			||||||
 | 
					are already adapted to the proper SQL literal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example: the Python function::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    curs.execute("""INSERT INTO atable (anint, adate, astring)
 | 
				
			||||||
 | 
					                     VALUES (%s, %s, %s)""",
 | 
				
			||||||
 | 
					                 (10, datetime.date(2005, 11, 18), "O'Reilly"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					is converted into the SQL command::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INSERT INTO atable (anint, adate, astring)
 | 
				
			||||||
 | 
					     VALUES (10, '2005-11-18', 'O''Reilly');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notice that:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - The Python string operator ``%`` is not used: the `curs.execute()` function
 | 
				
			||||||
 | 
					    accepts two parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - The variables placeholder must always be ``%s``, even if a different
 | 
				
			||||||
 | 
					    placeholder (such as a %d for an integer) may look more appropriate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - The second argument must always be a tuple, even if it contains a single
 | 
				
			||||||
 | 
					    parameter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - Only variable values should be bound via this method: it shouldn't be used
 | 
				
			||||||
 | 
					    to set table or field names. For these elements, ordinary string formatting
 | 
				
			||||||
 | 
					    should be used before running `.execute()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Adapting new types
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Any Python class or type can be adapted to an SQL string.  Adaptation mechanism
 | 
				
			||||||
 | 
					is similar to the Object Adaptation proposed in the `PEP-246`_ and is exposed
 | 
				
			||||||
 | 
					by the `adapt()` function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					psycopg2 `.execute()` method adapts its ``vars`` arguments to the `ISQLQuote`
 | 
				
			||||||
 | 
					protocol.  Objects that conform to this protocol expose a `getquoted()` method
 | 
				
			||||||
 | 
					returning the SQL representation of the object as a string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The easiest way to adapt an object to an SQL string is to register an adapter
 | 
				
			||||||
 | 
					function via the `register_adapter()` function.  The adapter function must take
 | 
				
			||||||
 | 
					the value to be adapted as argument and return a conform object.  A convenient
 | 
				
			||||||
 | 
					object is the `AsIs` wrapper, whose `getquoted()` result is simply the `str()`\
 | 
				
			||||||
 | 
					ingification of the wrapped object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example: mapping of a ``Point`` class into the ``point`` PostgreSQL geometric
 | 
				
			||||||
 | 
					type::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from psycopg2.extensions import adapt, register_adapter, AsIs
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    class Point(object):
 | 
				
			||||||
 | 
					        def __init__(self, x=0.0, y=0.0):
 | 
				
			||||||
 | 
					            self.x = x
 | 
				
			||||||
 | 
					            self.y = y
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def adapt_point(point):
 | 
				
			||||||
 | 
					        return AsIs("'(%s,%s)'" % (adapt(point.x), adapt(point.y)))
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    register_adapter(Point, adapt_point)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    curs.execute("INSERT INTO atable (apoint) VALUES (%s)", 
 | 
				
			||||||
 | 
					                 (Point(1.23, 4.56),))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above function call results in the SQL command::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INSERT INTO atable (apoint) VALUES ((1.23, 4.56));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _PEP-246: http://www.python.org/peps/pep-0246.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Type casting of SQL types into Python values
 | 
					Type casting of SQL types into Python values
 | 
				
			||||||
============================================
 | 
					============================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Extra type objects
 | 
					PostgreSQL objects read from the database can be adapted to Python objects.  To
 | 
				
			||||||
------------------
 | 
					create a new mapping from a PostgreSQL type (either standard or user-defined),
 | 
				
			||||||
 | 
					first its ``oid`` must be known.  It can be retrieved either by the second
 | 
				
			||||||
 | 
					column of the cursor description::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    curs.execute("SELECT NULL::point")
 | 
				
			||||||
 | 
					    point_oid = cur.description[0][1]   # usually returns 600
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					or by querying the system catalogs for the type name and namespace (the
 | 
				
			||||||
 | 
					namespace for system objects is ``pg_catalog``)::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    curs.execute("""
 | 
				
			||||||
 | 
					        SELECT pg_type.oid
 | 
				
			||||||
 | 
					          FROM pg_type JOIN pg_namespace
 | 
				
			||||||
 | 
					                 ON typnamespace = pg_namespace.oid
 | 
				
			||||||
 | 
					         WHERE typname = %(typename)s
 | 
				
			||||||
 | 
					           AND nspname = %(namespace)s""",
 | 
				
			||||||
 | 
					                {'typename': 'point', 'namespace': 'pg_catalog'})
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    point_oid = curs.fetchone()[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After you know the object ``oid``, you must create and register the new type
 | 
				
			||||||
 | 
					caster object::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def cast_point(value, curs):
 | 
				
			||||||
 | 
					        if value is not None:
 | 
				
			||||||
 | 
					        	# Convert from (f1, f2) syntax using a regular expression.
 | 
				
			||||||
 | 
					            m = re.match("\((.*),(.*)\)", value) 
 | 
				
			||||||
 | 
					            if m:
 | 
				
			||||||
 | 
					                return Point(float(m.group(1)), float(m.group(2)))
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					    POINT = psycopg2.extensions.new_type((point_oid,), "POINT", cast_point)
 | 
				
			||||||
 | 
					    psycopg2.extensions.register_type(POINT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `new_type()` function binds the object oids (more than one can be
 | 
				
			||||||
 | 
					specified) to a conversion function.  The function is called by psycopg passing
 | 
				
			||||||
 | 
					it the string representation of the data as returned by PostgreSQL and the
 | 
				
			||||||
 | 
					cursor: it should perform the conversion and return a Python type.
 | 
				
			||||||
 | 
					`register_type()` completes the spell::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    curs.execute("SELECT '(10.2,20.3)'::point")
 | 
				
			||||||
 | 
					    point = curs.fetchone()[0]
 | 
				
			||||||
 | 
					    print type(point), point.x, point.y
 | 
				
			||||||
 | 
					    # Prints: "<class '__main__.Point'> 10.2 20.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Working with times and dates
 | 
					Working with times and dates
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user