2010-02-26 03:17:52 +03:00
|
|
|
`psycopg2.extras` -- Miscellaneous goodies for Psycopg 2
|
2010-02-09 07:58:28 +03:00
|
|
|
=============================================================
|
|
|
|
|
|
|
|
.. sectionauthor:: Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
|
|
|
|
|
|
|
.. module:: psycopg2.extras
|
|
|
|
|
2010-02-13 19:06:39 +03:00
|
|
|
.. testsetup::
|
|
|
|
|
|
|
|
import psycopg2.extras
|
2010-02-14 23:32:35 +03:00
|
|
|
from psycopg2.extras import Inet
|
2010-02-13 19:06:39 +03:00
|
|
|
|
|
|
|
create_test_table()
|
|
|
|
|
2010-02-09 07:58:28 +03:00
|
|
|
This module is a generic place used to hold little helper functions and
|
|
|
|
classes until a better place in the distribution is found.
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
.. index::
|
|
|
|
pair: Cursor; Dictionary
|
|
|
|
|
|
|
|
.. _dict-cursor:
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
|
|
|
|
Connection and cursor subclasses
|
|
|
|
--------------------------------
|
|
|
|
|
|
|
|
A few objects that change the way the results are returned by the cursor or
|
|
|
|
modify the object behavior in some other way. Typically `!connection`
|
|
|
|
subclasses are passed as *connection_factory* argument to
|
|
|
|
`~psycopg2.connect()` so that the connection will generate the matching
|
|
|
|
`!cursor` subclass. Alternatively a `!cursor` subclass can be used one-off by
|
|
|
|
passing it as the *cursor_factory* argument to the `~connection.cursor()`
|
|
|
|
method of a regular `!connection`.
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
Dictionary-like cursor
|
2010-11-06 04:39:43 +03:00
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
The dict cursors allow to access to the retrieved records using an iterface
|
2010-11-06 04:39:43 +03:00
|
|
|
similar to the Python dictionaries instead of the tuples.
|
2010-02-13 05:10:51 +03:00
|
|
|
|
2010-02-13 19:06:39 +03:00
|
|
|
>>> dict_cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
>>> dict_cur.execute("INSERT INTO test (num, data) VALUES(%s, %s)",
|
|
|
|
... (100, "abc'def"))
|
|
|
|
>>> dict_cur.execute("SELECT * FROM test")
|
|
|
|
>>> rec = dict_cur.fetchone()
|
2010-02-13 05:10:51 +03:00
|
|
|
>>> rec['id']
|
|
|
|
1
|
|
|
|
>>> rec['num']
|
|
|
|
100
|
|
|
|
>>> rec['data']
|
|
|
|
"abc'def"
|
|
|
|
|
2010-02-14 08:02:09 +03:00
|
|
|
The records still support indexing as the original tuple:
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
>>> rec[2]
|
|
|
|
"abc'def"
|
|
|
|
|
|
|
|
|
|
|
|
.. autoclass:: DictCursor
|
|
|
|
|
|
|
|
.. autoclass:: DictConnection
|
|
|
|
|
|
|
|
.. autoclass:: DictRow
|
|
|
|
|
|
|
|
|
|
|
|
Real dictionary cursor
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: RealDictCursor
|
|
|
|
|
|
|
|
.. autoclass:: RealDictConnection
|
|
|
|
|
|
|
|
.. autoclass:: RealDictRow
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
.. index::
|
|
|
|
pair: Cursor; namedtuple
|
|
|
|
|
|
|
|
`namedtuple` cursor
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. versionadded:: 2.3
|
|
|
|
|
2011-02-19 19:16:28 +03:00
|
|
|
These objects require :py:func:`collections.namedtuple` to be found, so it is
|
2010-11-06 04:39:43 +03:00
|
|
|
available out-of-the-box only from Python 2.6. Anyway, the namedtuple
|
|
|
|
implementation is compatible with previous Python versions, so all you
|
2010-11-06 07:40:47 +03:00
|
|
|
have to do is to `download it`__ and make it available where we
|
2010-11-06 04:39:43 +03:00
|
|
|
expect it to be... ::
|
|
|
|
|
|
|
|
from somewhere import namedtuple
|
|
|
|
import collections
|
|
|
|
collections.namedtuple = namedtuple
|
|
|
|
from psycopg.extras import NamedTupleConnection
|
|
|
|
# ...
|
|
|
|
|
|
|
|
.. __: http://code.activestate.com/recipes/500261-named-tuples/
|
|
|
|
|
|
|
|
.. autoclass:: NamedTupleCursor
|
|
|
|
|
|
|
|
.. autoclass:: NamedTupleConnection
|
|
|
|
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
.. index::
|
|
|
|
pair: Cursor; Logging
|
|
|
|
|
|
|
|
Logging cursor
|
2010-11-06 04:39:43 +03:00
|
|
|
^^^^^^^^^^^^^^
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
.. autoclass:: LoggingConnection
|
|
|
|
:members: initialize,filter
|
|
|
|
|
|
|
|
.. autoclass:: LoggingCursor
|
|
|
|
|
|
|
|
|
|
|
|
.. autoclass:: MinTimeLoggingConnection
|
|
|
|
:members: initialize,filter
|
|
|
|
|
|
|
|
.. autoclass:: MinTimeLoggingCursor
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
.. index::
|
|
|
|
single: Data types; Additional
|
|
|
|
|
|
|
|
Additional data types
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
|
2010-09-27 05:25:09 +04:00
|
|
|
.. index::
|
|
|
|
pair: hstore; Data types
|
|
|
|
pair: dict; Adaptation
|
|
|
|
|
|
|
|
Hstore data type
|
2010-11-06 04:39:43 +03:00
|
|
|
^^^^^^^^^^^^^^^^
|
2010-09-27 05:25:09 +04:00
|
|
|
|
2010-11-05 15:38:49 +03:00
|
|
|
.. versionadded:: 2.3
|
2010-09-27 05:25:09 +04:00
|
|
|
|
2010-09-28 03:33:34 +04:00
|
|
|
The |hstore|_ data type is a key-value store embedded in PostgreSQL. It has
|
|
|
|
been available for several server versions but with the release 9.0 it has
|
|
|
|
been greatly improved in capacity and usefulness with the addiction of many
|
|
|
|
functions. It supports GiST or GIN indexes allowing search by keys or
|
|
|
|
key/value pairs as well as regular BTree indexes for equality, uniqueness etc.
|
2010-09-27 05:25:09 +04:00
|
|
|
|
2011-02-19 19:16:28 +03:00
|
|
|
Psycopg can convert Python `!dict` objects to and from |hstore| structures.
|
|
|
|
Only dictionaries with string/unicode keys and values are supported. `!None`
|
2011-02-25 03:19:49 +03:00
|
|
|
is also allowed as value but not as a key. Psycopg uses a more efficient |hstore|
|
2010-09-28 03:33:34 +04:00
|
|
|
representation when dealing with PostgreSQL 9.0 but previous server versions
|
2011-02-25 03:19:49 +03:00
|
|
|
are supported as well. By default the adapter/typecaster are disabled: they
|
2010-09-28 03:33:34 +04:00
|
|
|
can be enabled using the `register_hstore()` function.
|
|
|
|
|
|
|
|
.. autofunction:: register_hstore
|
2010-09-27 05:25:09 +04:00
|
|
|
|
|
|
|
.. |hstore| replace:: :sql:`hstore`
|
|
|
|
.. _hstore: http://www.postgresql.org/docs/9.0/static/hstore.html
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-02 02:34:13 +03:00
|
|
|
.. index::
|
|
|
|
pair: Composite types; Data types
|
|
|
|
pair: tuple; Adaptation
|
|
|
|
pair: namedtuple; Adaptation
|
|
|
|
|
|
|
|
Composite types casting
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
2011-02-15 14:00:08 +03:00
|
|
|
.. versionadded:: 2.4
|
2011-01-02 02:34:13 +03:00
|
|
|
|
|
|
|
Using `register_composite()` it is possible to cast a PostgreSQL composite
|
|
|
|
type (e.g. created with |CREATE TYPE|_ command) into a Python named tuple, or
|
2011-02-19 19:16:28 +03:00
|
|
|
into a regular tuple if :py:func:`collections.namedtuple` is not found.
|
2011-01-02 02:34:13 +03:00
|
|
|
|
|
|
|
.. |CREATE TYPE| replace:: :sql:`CREATE TYPE`
|
|
|
|
.. _CREATE TYPE: http://www.postgresql.org/docs/9.0/static/sql-createtype.html
|
|
|
|
|
|
|
|
.. doctest::
|
|
|
|
|
|
|
|
>>> cur.execute("CREATE TYPE card AS (value int, suit text);")
|
|
|
|
>>> psycopg2.extras.register_composite('card', cur)
|
|
|
|
<psycopg2.extras.CompositeCaster object at 0x...>
|
|
|
|
|
|
|
|
>>> cur.execute("select (8, 'hearts')::card")
|
|
|
|
>>> cur.fetchone()[0]
|
|
|
|
card(value=8, suit='hearts')
|
|
|
|
|
|
|
|
Nested composite types are handled as expected, but the type of the composite
|
|
|
|
components must be registered as well.
|
|
|
|
|
|
|
|
.. doctest::
|
|
|
|
|
|
|
|
>>> cur.execute("CREATE TYPE card_back AS (face card, back text);")
|
|
|
|
>>> psycopg2.extras.register_composite('card_back', cur)
|
|
|
|
<psycopg2.extras.CompositeCaster object at 0x...>
|
|
|
|
|
|
|
|
>>> cur.execute("select ((8, 'hearts'), 'blue')::card_back")
|
|
|
|
>>> cur.fetchone()[0]
|
|
|
|
card_back(face=card(value=8, suit='hearts'), back='blue')
|
|
|
|
|
|
|
|
Adaptation from Python tuples to composite types is automatic instead and
|
|
|
|
requires no adapter registration.
|
|
|
|
|
|
|
|
.. autofunction:: register_composite
|
|
|
|
|
|
|
|
.. autoclass:: CompositeCaster
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
.. index::
|
|
|
|
pair: UUID; Data types
|
|
|
|
|
|
|
|
UUID data type
|
2010-11-06 04:39:43 +03:00
|
|
|
^^^^^^^^^^^^^^
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
.. versionadded:: 2.0.9
|
|
|
|
.. versionchanged:: 2.0.13 added UUID array support.
|
|
|
|
|
2010-02-14 08:02:09 +03:00
|
|
|
.. doctest::
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
>>> psycopg2.extras.register_uuid()
|
2010-02-13 19:06:39 +03:00
|
|
|
<psycopg2._psycopg.type object at 0x...>
|
2010-02-14 08:02:09 +03:00
|
|
|
|
2010-02-13 19:06:39 +03:00
|
|
|
>>> # Python UUID can be used in SQL queries
|
|
|
|
>>> import uuid
|
2010-02-14 08:02:09 +03:00
|
|
|
>>> my_uuid = uuid.UUID('{12345678-1234-5678-1234-567812345678}')
|
|
|
|
>>> psycopg2.extensions.adapt(my_uuid).getquoted()
|
|
|
|
"'12345678-1234-5678-1234-567812345678'::uuid"
|
|
|
|
|
2010-02-13 19:06:39 +03:00
|
|
|
>>> # PostgreSQL UUID are transformed into Python UUID objects.
|
2010-02-13 05:10:51 +03:00
|
|
|
>>> 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
|
|
|
|
|
2010-02-14 23:32:35 +03:00
|
|
|
:sql:`inet` data type
|
2010-11-06 04:39:43 +03:00
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
2010-02-14 23:32:35 +03:00
|
|
|
|
|
|
|
.. versionadded:: 2.0.9
|
|
|
|
|
|
|
|
.. doctest::
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
>>> psycopg2.extras.register_inet()
|
2010-02-13 19:06:39 +03:00
|
|
|
<psycopg2._psycopg.type object at 0x...>
|
2010-02-14 23:32:35 +03:00
|
|
|
|
|
|
|
>>> cur.mogrify("SELECT %s", (Inet('127.0.0.1/32'),))
|
|
|
|
"SELECT E'127.0.0.1/32'::inet"
|
|
|
|
|
|
|
|
>>> cur.execute("SELECT '192.168.0.1/24'::inet")
|
2010-02-13 05:10:51 +03:00
|
|
|
>>> cur.fetchone()[0].addr
|
2010-02-14 23:32:35 +03:00
|
|
|
'192.168.0.1/24'
|
|
|
|
|
2010-02-13 05:10:51 +03:00
|
|
|
|
|
|
|
.. autofunction:: register_inet()
|
|
|
|
|
|
|
|
.. autoclass:: Inet
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. index::
|
|
|
|
single: Time zones; Fractional
|
|
|
|
|
|
|
|
Fractional time zones
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
.. autofunction:: register_tstz_w_secs
|
|
|
|
|
2010-02-13 08:49:34 +03:00
|
|
|
.. versionadded:: 2.0.9
|
|
|
|
|
2010-11-01 02:57:40 +03:00
|
|
|
.. versionchanged:: 2.2.2
|
2010-05-20 05:10:33 +04:00
|
|
|
function is no-op: see :ref:`tz-handling`.
|
|
|
|
|
2010-04-04 06:10:18 +04:00
|
|
|
.. index::
|
|
|
|
pair: Example; Coroutine;
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
|
|
|
|
|
2010-04-04 06:10:18 +04:00
|
|
|
Coroutine support
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
.. autofunction:: wait_select(conn)
|
|
|
|
|