Added documentation for the extras module.

This commit is contained in:
Daniele Varrazzo 2010-02-13 02:10:51 +00:00 committed by Federico Di Gregorio
parent ec68569e58
commit 6a4ff65b49
3 changed files with 164 additions and 22 deletions

View File

@ -8,4 +8,135 @@
This module is a generic place used to hold little helper functions and This module is a generic place used to hold little helper functions and
classes until a better place in the distribution is found. classes until a better place in the distribution is found.
.. todo:: psycopg2.extras
.. index::
pair: Cursor; Dictionary
.. _dict-cursor:
Dictionary-like cursor
----------------------
The dict cursors allow to access to the retrieved records using an iterface
similar to the Python dictionaries instead of the tuples. You can use it
either passing :class:`DictConnection` as :obj:`!connection_factory` argument
to the :func:`~psycopg2.connect` function or passing :class:`DictCursor` as
the :class:`!cursor_factory` argument to the :meth:`~connection.cursor` method
of a regular :class:`connection`. ::
>>> conn = psycopg2.connect(database='test')
>>> cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
>>> cur.execute("SELECT * FROM test")
>>> rec['id']
1
>>> rec['num']
100
>>> rec['data']
"abc'def"
# The records still support indexing as the original tuple
>>> rec[2]
"abc'def"
.. autoclass:: DictCursor
.. autoclass:: DictConnection
.. autoclass:: DictRow
Real dictionary cursor
^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: RealDictCursor
.. autoclass:: RealDictConnection
.. autoclass:: RealDictRow
.. index::
pair: Cursor; Logging
Logging cursor
--------------
.. autoclass:: LoggingConnection
:members: initialize,filter
.. autoclass:: LoggingCursor
.. autoclass:: MinTimeLoggingConnection
:members: initialize,filter
.. autoclass:: MinTimeLoggingCursor
.. index::
pair: UUID; Data types
UUID data type
--------------
.. versionadded:: 2.0.9
.. versionchanged:: 2.0.13 added UUID array support.
::
>>> psycopg2.extras.register_uuid()
# Python UUID can be used in SQL queries
>>> psycopg2.extensions.adapt(uuid.uuid4()).getquoted()
"'1ad2b180-c17e-46ad-ad94-e1f0dfc7c34b'::uuid"
# PostgreSQL UUID are transformed into Python UUID objects.
>>> conn = psycopg2.connect(database='test')
>>> cur = conn.cursor()
>>> cur.execute("SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid")
>>> cur.fetchone()[0]
UUID('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11')
.. autofunction:: register_uuid
.. autoclass:: UUID_adapter
.. index::
pair: INET; Data types
INET data type
--------------
::
>>> psycopg2.extras.register_inet()
>>> conn = psycopg2.connect(database='test')
>>> cur = conn.cursor()
>>> cur.execute("SELECT '192.168.0.1'::inet")
>>> cur.fetchone()[0].addr
'192.168.0.1'
.. autofunction:: register_inet()
.. autoclass:: Inet
.. todo:: Adapter non registered: how to register it?
.. index::
single: Time zones; Fractional
Fractional time zones
---------------------
.. versionadded:: 2.0.10
.. autofunction:: register_tstz_w_secs

View File

@ -227,7 +227,9 @@ Many standards Python types are adapted into SQL and returned as Python
objects when a query is executed. objects when a query is executed.
If you need to convert other Python types to and from PostgreSQL data types, If you need to convert other Python types to and from PostgreSQL data types,
see :ref:`adapting-new-types` and :ref:`type-casting-from-sql-to-python`. see :ref:`adapting-new-types` and :ref:`type-casting-from-sql-to-python`. You
can also find a few other specialized adapters in the :mod:`psycopg2.extras`
module.
In the following examples the method :meth:`~cursor.mogrify` is used to show In the following examples the method :meth:`~cursor.mogrify` is used to show
the SQL string that would be sent to the database. the SQL string that would be sent to the database.

View File

@ -97,7 +97,7 @@ class DictCursorBase(_cursor):
return res return res
class DictConnection(_connection): class DictConnection(_connection):
"""A connection that uses DictCursor automatically.""" """A connection that uses :class:`DictCursor` automatically."""
def cursor(self, name=None): def cursor(self, name=None):
if name is None: if name is None:
return _connection.cursor(self, cursor_factory=DictCursor) return _connection.cursor(self, cursor_factory=DictCursor)
@ -180,7 +180,7 @@ class DictRow(list):
return self._index.__contains__(x) return self._index.__contains__(x)
class RealDictConnection(_connection): class RealDictConnection(_connection):
"""A connection that uses RealDictCursor automatically.""" """A connection that uses :class:`RealDictCursor` automatically."""
def cursor(self, name=None): def cursor(self, name=None):
if name is None: if name is None:
return _connection.cursor(self, cursor_factory=RealDictCursor) return _connection.cursor(self, cursor_factory=RealDictCursor)
@ -193,7 +193,7 @@ class RealDictCursor(DictCursorBase):
Note that this cursor is extremely specialized and does not allow Note that this cursor is extremely specialized and does not allow
the normal access (using integer indices) to fetched data. If you need the normal access (using integer indices) to fetched data. If you need
to access database rows both as a dictionary and a list, then use to access database rows both as a dictionary and a list, then use
the generic DictCursor instead of RealDictCursor. the generic :class:`DictCursor` instead of :class:`!RealDictCursor`.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -218,6 +218,7 @@ class RealDictCursor(DictCursorBase):
self._query_executed = 0 self._query_executed = 0
class RealDictRow(dict): class RealDictRow(dict):
"""A ``dict`` subclass representing a data record."""
__slots__ = ('_column_mapping') __slots__ = ('_column_mapping')
@ -232,13 +233,16 @@ class RealDictRow(dict):
class LoggingConnection(_connection): class LoggingConnection(_connection):
"""A connection that logs all queries to a file or logger object.""" """A connection that logs all queries to a file or logger__ object.
.. __: http://docs.python.org/library/logging.html
"""
def initialize(self, logobj): def initialize(self, logobj):
"""Initialize the connection to log to `logobj`. """Initialize the connection to log to ``logobj``.
The `logobj` parameter can be an open file object or a Logger instance The ``logobj`` parameter can be an open file object or a Logger
from the standard logging module. instance from the standard logging module.
""" """
self._logobj = logobj self._logobj = logobj
if logging and isinstance(logobj, logging.Logger): if logging and isinstance(logobj, logging.Logger):
@ -294,12 +298,13 @@ class LoggingCursor(_cursor):
class MinTimeLoggingConnection(LoggingConnection): class MinTimeLoggingConnection(LoggingConnection):
"""A connection that logs queries based on execution time. """A connection that logs queries based on execution time.
This is just an example of how to sub-class LoggingConnection to provide This is just an example of how to sub-class :class:`LoggingConnection` to
some extra filtering for the logged queries. Both the `.inizialize()` and provide some extra filtering for the logged queries. Both the
`.filter()` methods are overwritten to make sure that only queries :meth:`inizialize` and :meth:`filter` methods are overwritten to make sure
executing for more than `mintime` ms are logged. that only queries executing for more than ``mintime`` ms are logged.
Note that this connection uses the specialized cursor MinTimeLoggingCursor. Note that this connection uses the specialized cursor
:class:`MinTimeLoggingCursor`.
""" """
def initialize(self, logobj, mintime=0): def initialize(self, logobj, mintime=0):
LoggingConnection.initialize(self, logobj) LoggingConnection.initialize(self, logobj)
@ -318,7 +323,7 @@ class MinTimeLoggingConnection(LoggingConnection):
return _connection.cursor(self, name, cursor_factory=MinTimeLoggingCursor) return _connection.cursor(self, name, cursor_factory=MinTimeLoggingCursor)
class MinTimeLoggingCursor(LoggingCursor): class MinTimeLoggingCursor(LoggingCursor):
"""The cursor sub-class companion to MinTimeLoggingConnection.""" """The cursor sub-class companion to :class:`MinTimeLoggingConnection`."""
def execute(self, query, vars=None, async=0): def execute(self, query, vars=None, async=0):
self.timestamp = time.time() self.timestamp = time.time()
@ -335,7 +340,11 @@ try:
import uuid import uuid
class UUID_adapter(object): class UUID_adapter(object):
"""Adapt Python's uuid.UUID type to PostgreSQL's uuid.""" """Adapt Python's uuid.UUID__ type to PostgreSQL's uuid__.
.. __: http://docs.python.org/library/uuid.html
.. __: http://www.postgresql.org/docs/8.4/static/datatype-uuid.html
"""
def __init__(self, uuid): def __init__(self, uuid):
self._uuid = uuid self._uuid = uuid
@ -440,7 +449,7 @@ def _convert_tstz_w_secs(s, cursor):
return DATETIME(s[:-3], cursor) return DATETIME(s[:-3], cursor)
def register_tstz_w_secs(oids=None, conn_or_curs=None): def register_tstz_w_secs(oids=None, conn_or_curs=None):
"""Register alternate type caster for TIMESTAMP WITH TIME ZONE. """Register alternate type caster for :sql:`TIMESTAMP WITH TIME ZONE`.
The Python datetime module cannot handle time zones with The Python datetime module cannot handle time zones with
seconds in the UTC offset. There are, however, historical seconds in the UTC offset. There are, however, historical
@ -451,16 +460,16 @@ def register_tstz_w_secs(oids=None, conn_or_curs=None):
timestamp you likely want to try this type caster. It truncates timestamp you likely want to try this type caster. It truncates
the seconds from the time zone data and retries casting the seconds from the time zone data and retries casting
the timestamp. Note that this will generate timestamps the timestamp. Note that this will generate timestamps
which are INACCURATE by the number of seconds truncated which are **inaccurate** by the number of seconds truncated
(unless the seconds were 00). (unless the seconds were 00).
<oids> :param oids:
which OIDs to use this type caster for, which OIDs to use this type caster for,
defaults to TIMESTAMP WITH TIME ZONE defaults to :sql:`TIMESTAMP WITH TIME ZONE`
<conn_or_curs> :param conn_or_curs:
a cursor or connection if you want to attach a cursor or connection if you want to attach
this type caster to that only, defaults to this type caster to that only, defaults to
None meaning all connections and cursors ``None`` meaning all connections and cursors
""" """
if oids is None: if oids is None:
oids = (1184,) # hardcoded from PostgreSQL headers oids = (1184,) # hardcoded from PostgreSQL headers