mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-12 07:10:33 +03:00
Added documentation for the extras module.
This commit is contained in:
parent
ec68569e58
commit
6a4ff65b49
133
doc/extras.rst
133
doc/extras.rst
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user