mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-10-30 23:37:29 +03:00 
			
		
		
		
	Added documentation to type casting objects.
This commit is contained in:
		
							parent
							
								
									74403ff5a8
								
							
						
					
					
						commit
						5491dd8db0
					
				|  | @ -61,18 +61,18 @@ by the :func:`psycopg2.extensions.adapt()` function. | ||||||
| 
 | 
 | ||||||
| The :meth:`cursor.execute()` method adapts its arguments to the | The :meth:`cursor.execute()` method adapts its arguments to the | ||||||
| :class:`psycopg2.extensions.ISQLQuote` protocol.  Objects that conform to this | :class:`psycopg2.extensions.ISQLQuote` protocol.  Objects that conform to this | ||||||
| protocol expose a ``getquoted()`` method returning the SQL representation of | protocol expose a :meth:`getquoted()` method returning the SQL representation | ||||||
| the object as a string. | of the object as a string. | ||||||
| 
 | 
 | ||||||
| The easiest way to adapt an object to an SQL string is to register an adapter | The easiest way to adapt an object to an SQL string is to register an adapter | ||||||
| function via the :func:`psycopg2.extensions.register_adapter()` function.  The | function via the :func:`psycopg2.extensions.register_adapter()` function.  The | ||||||
| adapter function must take the value to be adapted as argument and return a | adapter function must take the value to be adapted as argument and return a | ||||||
| conform object.  A convenient object is the :func:`psycopg2.extensions.AsIs` | conform object.  A convenient object is the :func:`psycopg2.extensions.AsIs` | ||||||
| wrapper, whose ``getquoted()`` result is simply the ``str()``\ ingification of | wrapper, whose :meth:`getquoted()` result is simply the ``str()``\ ing | ||||||
| the wrapped object. | conversion of the wrapped object. | ||||||
| 
 | 
 | ||||||
| Example: mapping of a ``Point`` class into the ``point`` PostgreSQL geometric | Example: mapping of a :data:`Point` class into the |point|_ PostgreSQL | ||||||
| type:: | geometric type:: | ||||||
| 
 | 
 | ||||||
|     from psycopg2.extensions import adapt, register_adapter, AsIs |     from psycopg2.extensions import adapt, register_adapter, AsIs | ||||||
| 
 | 
 | ||||||
|  | @ -89,6 +89,10 @@ type:: | ||||||
|     curs.execute("INSERT INTO atable (apoint) VALUES (%s)", |     curs.execute("INSERT INTO atable (apoint) VALUES (%s)", | ||||||
|                  (Point(1.23, 4.56),)) |                  (Point(1.23, 4.56),)) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | .. |point| replace:: ``point`` | ||||||
|  | .. _point: http://www.postgresql.org/docs/8.4/static/datatype-geometric.html#AEN6084 | ||||||
|  | 
 | ||||||
| The above function call results in the SQL command:: | The above function call results in the SQL command:: | ||||||
| 
 | 
 | ||||||
|     INSERT INTO atable (apoint) VALUES ((1.23, 4.56)); |     INSERT INTO atable (apoint) VALUES ((1.23, 4.56)); | ||||||
|  | @ -99,8 +103,8 @@ The above function call results in the SQL command:: | ||||||
| 
 | 
 | ||||||
| .. _type-casting-from-sql-to-python: | .. _type-casting-from-sql-to-python: | ||||||
| 
 | 
 | ||||||
| Type casting of SQL types into Python values | Type casting of SQL types into Python objects | ||||||
| -------------------------------------------- | --------------------------------------------- | ||||||
| 
 | 
 | ||||||
| PostgreSQL objects read from the database can be adapted to Python objects | PostgreSQL objects read from the database can be adapted to Python objects | ||||||
| through an user-defined adapting function.  An adapter function takes two | through an user-defined adapting function.  An adapter function takes two | ||||||
|  | @ -111,13 +115,13 @@ previously defined ``Point`` class:: | ||||||
| 
 | 
 | ||||||
|     def cast_point(value, curs): |     def cast_point(value, curs): | ||||||
|         if value is not None: |         if value is not None: | ||||||
|         	# Convert from (f1, f2) syntax using a regular expression. |             # Convert from (f1, f2) syntax using a regular expression. | ||||||
|             m = re.match("\((.*),(.*)\)", value)  |             m = re.match(r"\(([^)]+),([^)]+)\)", value) | ||||||
|             if m: |             if m: | ||||||
|                 return Point(float(m.group(1)), float(m.group(2))) |                 return Point(float(m.group(1)), float(m.group(2))) | ||||||
| 
 | 
 | ||||||
| To create a mapping from the PostgreSQL type (either standard or user-defined), | To create a mapping from the PostgreSQL type (either standard or user-defined), | ||||||
| its ``oid`` must be known. It can be retrieved either by the second column of | its OID must be known. It can be retrieved either by the second column of | ||||||
| the cursor description:: | the cursor description:: | ||||||
| 
 | 
 | ||||||
|     curs.execute("SELECT NULL::point") |     curs.execute("SELECT NULL::point") | ||||||
|  | @ -132,11 +136,11 @@ namespace for system objects is ``pg_catalog``):: | ||||||
|                  ON typnamespace = pg_namespace.oid |                  ON typnamespace = pg_namespace.oid | ||||||
|          WHERE typname = %(typename)s |          WHERE typname = %(typename)s | ||||||
|            AND nspname = %(namespace)s""", |            AND nspname = %(namespace)s""", | ||||||
|                 {'typename': 'point', 'namespace': 'pg_catalog'}) |         {'typename': 'point', 'namespace': 'pg_catalog'}) | ||||||
| 
 | 
 | ||||||
|     point_oid = curs.fetchone()[0] |     point_oid = curs.fetchone()[0] | ||||||
| 
 | 
 | ||||||
| After you know the object ``oid``, you must can and register the new type:: | After you know the object OID, you must can and register the new type:: | ||||||
| 
 | 
 | ||||||
|     POINT = psycopg2.extensions.new_type((point_oid,), "POINT", cast_point) |     POINT = psycopg2.extensions.new_type((point_oid,), "POINT", cast_point) | ||||||
|     psycopg2.extensions.register_type(POINT) |     psycopg2.extensions.register_type(POINT) | ||||||
|  | @ -144,7 +148,7 @@ After you know the object ``oid``, you must can and register the new type:: | ||||||
| The :func:`psycopg2.extensions.new_type()` function binds the object oids | The :func:`psycopg2.extensions.new_type()` function binds the object oids | ||||||
| (more than one can be specified) to the adapter function. | (more than one can be specified) to the adapter function. | ||||||
| :func:`psycopg2.extensions.register_type()` completes the spell.  Conversion | :func:`psycopg2.extensions.register_type()` completes the spell.  Conversion | ||||||
| is automatically performed when a column whose type is a registered ``oid`` is | is automatically performed when a column whose type is a registered OID is | ||||||
| read:: | read:: | ||||||
| 
 | 
 | ||||||
|     >>> curs.execute("SELECT '(10.2,20.3)'::point") |     >>> curs.execute("SELECT '(10.2,20.3)'::point") | ||||||
|  |  | ||||||
|  | @ -36,7 +36,167 @@ functionalities defined by the |DBAPI|. | ||||||
|     .. todo:: class lobject |     .. todo:: class lobject | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. todo:: finish module extensions | 
 | ||||||
|  | .. _sql-adaptation-objects: | ||||||
|  | 
 | ||||||
|  | SQL adaptation protocol objects | ||||||
|  | ------------------------------- | ||||||
|  | 
 | ||||||
|  | Psycopg provides a flexible system to adapt Python objects to the SQL syntax | ||||||
|  | (inspired to the :pep:`246`), allowing serialization in PostgreSQL. See | ||||||
|  | :ref:`adapting-new-types` for a detailed description.  The following objects | ||||||
|  | deal with Python objects adaptation: | ||||||
|  | 
 | ||||||
|  | .. function:: adapt(obj) | ||||||
|  | 
 | ||||||
|  |     Return the SQL representation of :obj:`obj` as a string.  Raise a | ||||||
|  |     :exc:`ProgrammingError` if how to adapt the object is unknown.  In order | ||||||
|  |     to allow new objects to be adapted, register a new adapter for it using | ||||||
|  |     the :func:`register_adapter` function. | ||||||
|  | 
 | ||||||
|  |     The function is the entry point of the adaptation mechanism: it can be | ||||||
|  |     used to write adapters for complex objects by recursively calling | ||||||
|  |     :func:`adapt` on its components. | ||||||
|  | 
 | ||||||
|  | .. function:: register_adapter(class, adapter) | ||||||
|  | 
 | ||||||
|  |     Register a new adapter for the objects of class :data:`class`. | ||||||
|  | 
 | ||||||
|  |     :data:`adapter` should be a function taking a single argument (the object | ||||||
|  |     to adapt) and returning an object conforming the :class:`ISQLQuote` | ||||||
|  |     protocol (e.g. exposing a :meth:`getquoted` method).  The :class:`AsIs` is | ||||||
|  |     often useful for this task. | ||||||
|  | 
 | ||||||
|  |     Once an object is registered, it can be safely used in SQL queries and by | ||||||
|  |     the :func:`adapt` function. | ||||||
|  | 
 | ||||||
|  | .. class:: ISQLQuote | ||||||
|  | 
 | ||||||
|  |     Represents the SQL adaptation protocol. Objects conforming this protocol | ||||||
|  |     should implement a :meth:`getquoted` method. | ||||||
|  | 
 | ||||||
|  |     .. todo:: has Psycopg user ever to explicitely use this object? | ||||||
|  | 
 | ||||||
|  |     .. todo:: | ||||||
|  |         what the ISQLQuote methods are for? In my understanding the | ||||||
|  |         class is only used as symbol to dispatch adaptation and not to be | ||||||
|  |         instantiated. | ||||||
|  | 
 | ||||||
|  | .. class:: AsIs | ||||||
|  | 
 | ||||||
|  |     Adapter conform to the :class:`ISQLQuote` protocol useful for objects | ||||||
|  |     whose string representation is already valid as SQL representation. | ||||||
|  | 
 | ||||||
|  |     .. method:: getquoted() | ||||||
|  | 
 | ||||||
|  |         Return the ``str()`` conversion of the wrapped object. :: | ||||||
|  | 
 | ||||||
|  |             >>> AsIs(42).getquoted() | ||||||
|  |             '42' | ||||||
|  | 
 | ||||||
|  | .. class:: QuotedString | ||||||
|  | 
 | ||||||
|  |     Adapter conform to the :class:`ISQLQuote` protocol for string-like | ||||||
|  |     objects. | ||||||
|  | 
 | ||||||
|  |     .. method:: getquoted() | ||||||
|  | 
 | ||||||
|  |         Return the string enclosed in single quotes.  Any single quote | ||||||
|  |         appearing in the the string is escaped by doubling it according to SQL | ||||||
|  |         string constants syntax.  Backslashes are escaped too. | ||||||
|  | 
 | ||||||
|  |             >>> QuotedString(r"O'Reilly").getquoted() | ||||||
|  |             "'O''Reilly'" | ||||||
|  | 
 | ||||||
|  | .. class:: Binary | ||||||
|  | 
 | ||||||
|  |     Adapter conform to the :class:`ISQLQuote` protocol for binary objects. | ||||||
|  | 
 | ||||||
|  |     .. method:: getquoted() | ||||||
|  | 
 | ||||||
|  |         Return the string enclosed in single quotes.  It performs the same | ||||||
|  |         escaping of the :class:`QuotedString` adapter, plus it knows how to | ||||||
|  |         escape non-printable chars. | ||||||
|  | 
 | ||||||
|  |             >>> Binary("\x00\x08\x0F").getquoted() | ||||||
|  |             "'\\\\000\\\\010\\\\017'" | ||||||
|  | 
 | ||||||
|  |     .. todo:: | ||||||
|  | 
 | ||||||
|  |         this class is actually not importd in module extensions: I'd say this | ||||||
|  |         is a bug. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .. data:: Boolean | ||||||
|  | .. data:: Float | ||||||
|  | 
 | ||||||
|  | Specialized adapters for builtin objects. | ||||||
|  | 
 | ||||||
|  | .. data:: DateFromPy | ||||||
|  | .. data:: TimeFromPy | ||||||
|  | .. data:: TimestampFromPy | ||||||
|  | .. data:: IntervalFromPy | ||||||
|  | 
 | ||||||
|  | Specialized adapters for Python datetime objects. | ||||||
|  | 
 | ||||||
|  | .. data:: DateFromMx | ||||||
|  | .. data:: TimeFromMx | ||||||
|  | .. data:: TimestampFromMx | ||||||
|  | .. data:: IntervalFromMx | ||||||
|  | 
 | ||||||
|  | Specialized adapters for `mx.DateTime`_ objects. | ||||||
|  | 
 | ||||||
|  | .. data:: adapters | ||||||
|  | 
 | ||||||
|  |     Dictionary of the currently registered object adapters.  Use | ||||||
|  |     :func:`register_adapter` to add an adapter for a new type. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Database types casting functions | ||||||
|  | -------------------------------- | ||||||
|  | 
 | ||||||
|  | These functions are used to manipulate type casters to convert from PostgreSQL | ||||||
|  | types to Python objects.  See :ref:`type-casting-from-sql-to-python` for | ||||||
|  | details. | ||||||
|  | 
 | ||||||
|  | .. function:: new_type(oids, name, adapter) | ||||||
|  | 
 | ||||||
|  |     Create a new type caster to convert from a PostgreSQL type to a Python | ||||||
|  |     object.  The created object must be registered using | ||||||
|  |     :func:`register_type` to be used. | ||||||
|  | 
 | ||||||
|  |     :param oids: tuple of OIDs of the PostgreSQL type to convert. | ||||||
|  |     :param name: the name of the new type adapter. | ||||||
|  |     :param adapter: the adaptation function. | ||||||
|  | 
 | ||||||
|  |     The object OID can be read from the :data:`cursor.description` or directly | ||||||
|  |     from the PostgreSQL catalog. | ||||||
|  | 
 | ||||||
|  |     :data:`adapter` should have signature ``fun(value, cur)`` where | ||||||
|  |     ``value`` is the string representation returned by PostgreSQL and ``cur`` | ||||||
|  |     is the cursor from which data are read. In case of ``NULL``, ``value`` is | ||||||
|  |     ``None``. The adapter should return the converted object. | ||||||
|  | 
 | ||||||
|  |     See :ref:`type-casting-from-sql-to-python` for an usage example. | ||||||
|  | 
 | ||||||
|  | .. function:: register_type(obj [, scope]) | ||||||
|  | 
 | ||||||
|  |     Register a type caster created using :func:`new_type`. | ||||||
|  | 
 | ||||||
|  |     If :obj:`scope` is specified, it should be a :class:`connection` or a | ||||||
|  |     :class:`cursor`: the type caster will be effective only limited to the | ||||||
|  |     specified object.  Otherwise it will be globally registered. | ||||||
|  | 
 | ||||||
|  |     .. todo:: Please confirm the above behaviour. | ||||||
|  | 
 | ||||||
|  | .. data:: string_types | ||||||
|  | 
 | ||||||
|  |     The global register of type casters. | ||||||
|  | 
 | ||||||
|  | .. data:: binary_types | ||||||
|  | 
 | ||||||
|  |     .. todo:: is this used? | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -306,7 +306,14 @@ the SQL string that would be sent to the database. | ||||||
|     SQL doesn't allow an empty list in the IN operator, so your code should |     SQL doesn't allow an empty list in the IN operator, so your code should | ||||||
|     guard against empty tuples. |     guard against empty tuples. | ||||||
| 
 | 
 | ||||||
|  |   .. note:: | ||||||
| 
 | 
 | ||||||
|  |     In order to use the tuple adapter, your application must import the module | ||||||
|  |     :mod:`psycopg2.extensions`. | ||||||
|  | 
 | ||||||
|  |     .. todo:: is this a bug or a feature? | ||||||
|  | 
 | ||||||
|  |   .. versionadded:: 2.0.6 | ||||||
| 
 | 
 | ||||||
| .. index:: | .. index:: | ||||||
|     pair: Server side; Cursor |     pair: Server side; Cursor | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user