summaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorAshesh Vashi <asheshv@users.noreply.github.com>2018-05-08 15:17:59 +0530
committerGitHub <noreply@github.com>2018-05-08 15:17:59 +0530
commit1bec2bdc437d89847919889f20825e2ca94c8fa0 (patch)
tree9a1152781b41e61a8c15a8182c3e6e9cca96899f /doc/src
parent84d405894c4236c1d2bb54c673a71e4a8e78a2ec (diff)
parent90b26c3e2369e4aa9cf4a70f8ff1e17b06607de0 (diff)
downloadpsycopg2-1bec2bdc437d89847919889f20825e2ca94c8fa0.tar.gz
Merge branch 'master' into master
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/advanced.rst6
-rw-r--r--doc/src/conf.py6
-rw-r--r--doc/src/connection.rst19
-rw-r--r--doc/src/cursor.rst44
-rw-r--r--doc/src/errorcodes.rst4
-rw-r--r--doc/src/extras.rst40
-rw-r--r--doc/src/faq.rst5
-rw-r--r--doc/src/index.rst1
-rw-r--r--doc/src/install.rst185
-rw-r--r--doc/src/pool.rst10
-rwxr-xr-xdoc/src/tools/lib/dbapi_extension.py14
-rw-r--r--doc/src/tools/lib/sql_role.py5
-rw-r--r--doc/src/tools/lib/ticket_role.py1
-rwxr-xr-xdoc/src/tools/stitch_text.py16
-rw-r--r--doc/src/tz.rst3
-rw-r--r--doc/src/usage.rst111
16 files changed, 240 insertions, 230 deletions
diff --git a/doc/src/advanced.rst b/doc/src/advanced.rst
index 5b5fb35..d1683b8 100644
--- a/doc/src/advanced.rst
+++ b/doc/src/advanced.rst
@@ -188,7 +188,7 @@ representation into the previously defined `!Point` class:
... return Point(float(m.group(1)), float(m.group(2)))
... else:
... raise InterfaceError("bad point representation: %r" % value)
-
+
In order to create a mapping from a PostgreSQL type (either standard or
user-defined), its OID must be known. It can be retrieved either by the second
@@ -295,7 +295,9 @@ something to read::
print "Got NOTIFY:", notify.pid, notify.channel, notify.payload
Running the script and executing a command such as :sql:`NOTIFY test, 'hello'`
-in a separate :program:`psql` shell, the output may look similar to::
+in a separate :program:`psql` shell, the output may look similar to:
+
+.. code-block:: none
Waiting for notifications on channel 'test'
Timeout
diff --git a/doc/src/conf.py b/doc/src/conf.py
index 9e73308..a27d6cf 100644
--- a/doc/src/conf.py
+++ b/doc/src/conf.py
@@ -57,7 +57,7 @@ try:
release = psycopg2.__version__.split()[0]
version = '.'.join(release.split('.')[:2])
except ImportError:
- print "WARNING: couldn't import psycopg to read version."
+ print("WARNING: couldn't import psycopg to read version.")
release = version
intersphinx_mapping = {
@@ -101,6 +101,10 @@ default_role = 'obj'
# output. They are ignored by default.
#show_authors = False
+# Using 'python' instead of the default gives warnings if parsing an example
+# fails, instead of defaulting to none
+highlight_language = 'python'
+
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
diff --git a/doc/src/connection.rst b/doc/src/connection.rst
index 2d720ee..d656fa1 100644
--- a/doc/src/connection.rst
+++ b/doc/src/connection.rst
@@ -22,7 +22,7 @@ The ``connection`` class
:ref:`thread-safety` for details.
.. method:: cursor(name=None, cursor_factory=None, scrollable=None, withhold=False)
-
+
Return a new `cursor` object using the connection.
If *name* is specified, the returned cursor will be a :ref:`server
@@ -41,11 +41,6 @@ The ``connection`` class
previously only valid PostgreSQL identifiers were accepted as
cursor name.
- .. warning::
- It is unsafe to expose the *name* to an untrusted source, for
- instance you shouldn't allow *name* to be read from a HTML form.
- Consider it as part of the query, not as a query parameter.
-
The *cursor_factory* argument can be used to create non-standard
cursors. The class returned must be a subclass of
`psycopg2.extensions.cursor`. See :ref:`subclassing-cursor` for
@@ -274,8 +269,8 @@ The ``connection`` class
.. __: http://jdbc.postgresql.org/
- Xids returned by `!tpc_recover()` also have extra attributes
- `~psycopg2.extensions.Xid.prepared`, `~psycopg2.extensions.Xid.owner`,
+ Xids returned by `!tpc_recover()` also have extra attributes
+ `~psycopg2.extensions.Xid.prepared`, `~psycopg2.extensions.Xid.owner`,
`~psycopg2.extensions.Xid.database` populated with the values read
from the server.
@@ -551,7 +546,7 @@ The ``connection`` class
the session.
.. doctest::
- :options: NORMALIZE_WHITESPACE
+ :options: +NORMALIZE_WHITESPACE
>>> cur.execute("CREATE TABLE foo (id serial PRIMARY KEY);")
>>> pprint(conn.notices)
@@ -626,7 +621,7 @@ The ``connection`` class
pair: Server; Parameters
.. method:: get_parameter_status(parameter)
-
+
Look up a current parameter setting of the server.
Potential values for ``parameter`` are: ``server_version``,
@@ -735,7 +730,7 @@ The ``connection`` class
The number is formed by converting the major, minor, and revision
numbers into two-decimal-digit numbers and appending them together.
For example, version 8.1.5 will be returned as ``80105``.
-
+
.. seealso:: libpq docs for `PQserverVersion()`__ for details.
.. __: http://www.postgresql.org/docs/current/static/libpq-status.html#LIBPQ-PQSERVERVERSION
@@ -749,7 +744,7 @@ The ``connection`` class
.. attribute:: status
A read-only integer representing the status of the connection.
- Symbolic constants for the values are defined in the module
+ Symbolic constants for the values are defined in the module
`psycopg2.extensions`: see :ref:`connection-status-constants`
for the available values.
diff --git a/doc/src/cursor.rst b/doc/src/cursor.rst
index 417ab6c..5a6935e 100644
--- a/doc/src/cursor.rst
+++ b/doc/src/cursor.rst
@@ -34,10 +34,10 @@ The ``cursor`` class
many cursors from the same connection and should use each cursor from
a single thread. See :ref:`thread-safety` for details.
-
- .. attribute:: description
- This read-only attribute is a sequence of 7-item sequences.
+ .. attribute:: description
+
+ This read-only attribute is a sequence of 7-item sequences.
Each of these sequences is a named tuple (a regular tuple if
:func:`collections.namedtuple` is not available) containing information
@@ -65,7 +65,7 @@ The ``cursor`` class
This attribute will be `!None` for operations that do not return rows
or if the cursor has not had an operation invoked via the
|execute*|_ methods yet.
-
+
.. |pg_type| replace:: :sql:`pg_type`
.. _pg_type: http://www.postgresql.org/docs/current/static/catalog-pg-type.html
.. _PQgetlength: http://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQGETLENGTH
@@ -78,7 +78,7 @@ The ``cursor`` class
regular tuples.
.. method:: close()
-
+
Close the cursor now (rather than whenever `del` is executed).
The cursor will be unusable from this point forward; an
`~psycopg2.InterfaceError` will be raised if any operation is
@@ -88,7 +88,7 @@ The ``cursor`` class
the method is automatically called at the end of the ``with``
block.
-
+
.. attribute:: closed
Read-only boolean attribute: specifies if the cursor is closed
@@ -235,7 +235,7 @@ The ``cursor`` class
The `mogrify()` method is a Psycopg extension to the |DBAPI|.
.. method:: setinputsizes(sizes)
-
+
This method is exposed in compliance with the |DBAPI|. It currently
does nothing but it is safe to call it.
@@ -281,17 +281,17 @@ The ``cursor`` class
>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone()
(3, 42, 'bar')
-
+
A `~psycopg2.ProgrammingError` is raised if the previous call
to |execute*|_ did not produce any result set or no call was issued
yet.
.. method:: fetchmany([size=cursor.arraysize])
-
+
Fetch the next set of rows of a query result, returning a list of
tuples. An empty list is returned when no more rows are available.
-
+
The number of rows to fetch per call is specified by the parameter.
If it is not given, the cursor's `~cursor.arraysize` determines
the number of rows to be fetched. The method should try to fetch as
@@ -309,7 +309,7 @@ The ``cursor`` class
A `~psycopg2.ProgrammingError` is raised if the previous call to
|execute*|_ did not produce any result set or no call was issued yet.
-
+
Note there are performance considerations involved with the size
parameter. For optimal performance, it is usually best to use the
`~cursor.arraysize` attribute. If the size parameter is used,
@@ -344,7 +344,7 @@ The ``cursor`` class
`~psycopg2.ProgrammingError` is raised and the cursor position is
not changed.
- .. note::
+ .. note::
According to the |DBAPI|_, the exception raised for a cursor out
of bound should have been `!IndexError`. The best option is
@@ -364,7 +364,7 @@ The ``cursor`` class
.. attribute:: arraysize
-
+
This read/write attribute specifies the number of rows to fetch at a
time with `~cursor.fetchmany()`. It defaults to 1 meaning to fetch
a single row at a time.
@@ -378,20 +378,20 @@ The ``cursor`` class
default is 2000.
.. versionadded:: 2.4
-
+
.. extension::
The `itersize` attribute is a Psycopg extension to the |DBAPI|.
- .. attribute:: rowcount
-
+ .. attribute:: rowcount
+
This read-only attribute specifies the number of rows that the last
|execute*|_ produced (for :abbr:`DQL (Data Query Language)` statements
- like :sql:`SELECT`) or affected (for
+ like :sql:`SELECT`) or affected (for
:abbr:`DML (Data Manipulation Language)` statements like :sql:`UPDATE`
or :sql:`INSERT`).
-
+
The attribute is -1 in case no |execute*| has been performed on
the cursor or the row count of the last operation if it can't be
determined by the interface.
@@ -400,7 +400,7 @@ The ``cursor`` class
The |DBAPI|_ interface reserves to redefine the latter case to
have the object return `!None` instead of -1 in future versions
of the specification.
-
+
.. attribute:: rownumber
@@ -457,7 +457,7 @@ The ``cursor`` class
command:
>>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
- >>> cur.statusmessage
+ >>> cur.statusmessage
'INSERT 0 1'
.. extension::
@@ -490,13 +490,13 @@ The ``cursor`` class
.. method:: nextset()
-
+
This method is not supported (PostgreSQL does not have multiple data
sets) and will raise a `~psycopg2.NotSupportedError` exception.
.. method:: setoutputsize(size [, column])
-
+
This method is exposed in compliance with the |DBAPI|. It currently
does nothing but it is safe to call it.
diff --git a/doc/src/errorcodes.rst b/doc/src/errorcodes.rst
index ed40b1f..ab49afb 100644
--- a/doc/src/errorcodes.rst
+++ b/doc/src/errorcodes.rst
@@ -50,7 +50,7 @@ An example of the available constants defined in the module:
'42P01'
Constants representing all the error values defined by PostgreSQL versions
-between 8.1 and 10 beta 1 are included in the module.
+between 8.1 and 10 are included in the module.
.. autofunction:: lookup(code)
@@ -59,7 +59,7 @@ between 8.1 and 10 beta 1 are included in the module.
>>> try:
... cur.execute("SELECT ouch FROM aargh;")
- ... except Exception, e:
+ ... except Exception as e:
... pass
...
>>> errorcodes.lookup(e.pgcode[:2])
diff --git a/doc/src/extras.rst b/doc/src/extras.rst
index 36118e7..15f35e8 100644
--- a/doc/src/extras.rst
+++ b/doc/src/extras.rst
@@ -99,20 +99,6 @@ Real dictionary cursor
.. versionadded:: 2.3
-These objects require :py:func:`collections.namedtuple` to be found, so it is
-available out-of-the-box only from Python 2.6. Anyway, the namedtuple
-implementation is compatible with previous Python versions, so all you
-have to do is to `download it`__ and make it available where we
-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
@@ -403,7 +389,7 @@ The individual messages in the replication stream are represented by
class LogicalStreamConsumer(object):
- ...
+ # ...
def __call__(self, msg):
self.process_message(msg.payload)
@@ -501,7 +487,7 @@ The individual messages in the replication stream are represented by
from datetime import datetime
def consume(msg):
- ...
+ # ...
keepalive_interval = 10.0
while True:
@@ -553,17 +539,13 @@ fields to JSON) you can use the `register_json()` function.
.. __: http://people.planetpostgresql.org/andrew/index.php?/archives/255-JSON-for-PG-9.2-...-and-now-for-9.1!.html
-The Python library used by default to convert Python objects to JSON and to
-parse data from the database depends on the language version: with Python 2.6
-and following the :py:mod:`json` module from the standard library is used;
-with previous versions the `simplejson`_ module is used if available. Note
-that the last `!simplejson` version supporting Python 2.4 is the 2.0.9.
+The Python :py:mod:`json` module is used by default to convert Python objects
+to JSON and to parse data from the database.
.. _JSON: http://www.json.org/
.. |pgjson| replace:: :sql:`json`
.. |jsonb| replace:: :sql:`jsonb`
.. _pgjson: http://www.postgresql.org/docs/current/static/datatype-json.html
-.. _simplejson: http://pypi.python.org/pypi/simplejson/
In order to pass a Python object to the database as query argument you can use
the `Json` adapter::
@@ -1043,20 +1025,6 @@ parameters. By reducing the number of server roundtrips the performance can be
.. versionadded:: 2.7
-
-.. index::
- single: Time zones; Fractional
-
-Fractional time zones
----------------------
-
-.. autofunction:: register_tstz_w_secs
-
- .. versionadded:: 2.0.9
-
- .. versionchanged:: 2.2.2
- function is no-op: see :ref:`tz-handling`.
-
.. index::
pair: Example; Coroutine;
diff --git a/doc/src/faq.rst b/doc/src/faq.rst
index fb7b33d..5824d2b 100644
--- a/doc/src/faq.rst
+++ b/doc/src/faq.rst
@@ -306,7 +306,9 @@ I can't compile `!psycopg2`: the compiler says *error: libpq-fe.h: No such file
API support (*i.e.* the libpq used at compile time was at least 9.3) but
at runtime an older libpq dynamic library is found.
- You can use::
+ You can use:
+
+ .. code-block:: shell
$ ldd /path/to/packages/psycopg2/_psycopg.so | grep libpq
@@ -332,4 +334,3 @@ Psycopg raises *ImportError: cannot import name tz* on import in mod_wsgi / ASP,
.. _egg: http://peak.telecommunity.com/DevCenter/PythonEggs
.. __: http://stackoverflow.com/questions/2192323/what-is-the-python-egg-cache-python-egg-cache
.. __: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPythonEggs
-
diff --git a/doc/src/index.rst b/doc/src/index.rst
index 30ba8fa..852bbc2 100644
--- a/doc/src/index.rst
+++ b/doc/src/index.rst
@@ -65,4 +65,3 @@ Psycopg 2 is both Unicode and Python 3 friendly.
**To Do items in the documentation**
.. todolist::
-
diff --git a/doc/src/install.rst b/doc/src/install.rst
index 9119753..a858cbe 100644
--- a/doc/src/install.rst
+++ b/doc/src/install.rst
@@ -12,16 +12,6 @@ to use Psycopg on a different Python implementation (PyPy, Jython, IronPython)
there is an experimental `porting of Psycopg for Ctypes`__, but it is not as
mature as the C implementation yet.
-The current `!psycopg2` implementation supports:
-
-..
- NOTE: keep consistent with setup.py and the /features/ page.
-
-- Python 2 versions from 2.6 to 2.7
-- Python 3 versions from 3.2 to 3.6
-- PostgreSQL server versions from 7.4 to 9.6
-- PostgreSQL client library version from 9.1
-
.. _PostgreSQL: http://www.postgresql.org/
.. _Python: http://www.python.org/
.. _libpq: http://www.postgresql.org/docs/current/static/libpq.html
@@ -32,77 +22,20 @@ The current `!psycopg2` implementation supports:
.. index::
- single: Install; from PyPI
-
-Binary install from PyPI
-------------------------
-
-`!psycopg2` is `available on PyPI`__ in the form of wheel_ packages for the
-most common platform (Linux, OSX, Windows): this should make you able to
-install a binary version of the module including all the dependencies simply
-using:
-
-.. code-block:: console
-
- $ pip install psycopg2
-
-Make sure to use an up-to-date version of :program:`pip` (you can upgrade it
-using something like ``pip install -U pip``)
-
-.. __: PyPI_
-.. _PyPI: https://pypi.python.org/pypi/psycopg2/
-.. _wheel: http://pythonwheels.com/
-
-.. note::
-
- The binary packages come with their own versions of a few C libraries,
- among which ``libpq`` and ``libssl``, which will be used regardless of other
- libraries available on the client: upgrading the system libraries will not
- upgrade the libraries used by `!psycopg2`. Please build `!psycopg2` from
- source if you want to maintain binary upgradeability.
-
-.. warning::
-
- Because the `!psycopg` wheel package uses its own ``libssl`` binary, it is
- incompatible with other extension modules binding with ``libssl`` as well,
- for instance the Python `ssl` module: the result will likely be a
- segfault. If you need using both `!psycopg2` and other libraries using
- ``libssl`` please :ref:`install psycopg from source
- <install-from-source>`.
-
-If you prefer to use the system libraries available on your client you can use
-the :command:`pip` ``--no-binary`` option:
-
-.. code-block:: console
-
- $ pip install --no-binary psycopg2
-
-which can be specified in your :file:`requirements.txt` files too, e.g. use:
-
-.. code-block:: none
-
- psycopg2>=2.7,<2.8 --no-binary :all:
-
-to use the last bugfix release of the `!psycopg2` 2.7 package, specifying to
-always compile it from source. Of course in this case you will have to meet
-the :ref:`build prerequisites <build-prerequisites>`.
-
-
-
-.. index::
- single: Install; from source
+ single: Prerequisites
-.. _install-from-source:
+Prerequisites
+-------------
-Install from source
--------------------
-
-.. _source-package:
+The current `!psycopg2` implementation supports:
-You can download a copy of Psycopg source files from the `Psycopg download
-page`__ or from PyPI_.
+..
+ NOTE: keep consistent with setup.py and the /features/ page.
-.. __: http://initd.org/psycopg/download/
+- Python version 2.7
+- Python 3 versions from 3.4 to 3.6
+- PostgreSQL server versions from 7.4 to 10
+- PostgreSQL client library version from 9.1
@@ -111,8 +44,8 @@ page`__ or from PyPI_.
Build prerequisites
^^^^^^^^^^^^^^^^^^^
-These notes illustrate how to compile Psycopg on Linux. If you want to compile
-Psycopg on other platforms you may have to adjust some details accordingly.
+The build prerequisites are to be met in order to install Psycopg from source
+code, either from a source distribution package or from PyPI.
Psycopg is a C wrapper around the libpq_ PostgreSQL client library. To install
it from sources you will need:
@@ -146,6 +79,12 @@ Once everything is in place it's just a matter of running the standard:
.. code-block:: console
+ $ pip install psycopg2
+
+or, from the directory containing the source code:
+
+.. code-block:: console
+
$ python setup.py build
$ python setup.py install
@@ -181,11 +120,91 @@ which is OS-dependent (for instance setting a suitable
.. index::
+ single: Install; from PyPI
+ single: Install; wheel
+ single: Wheel
+
+Binary install from PyPI
+------------------------
+
+`!psycopg2` is also `available on PyPI`__ in the form of wheel_ packages for
+the most common platform (Linux, OSX, Windows): this should make you able to
+install a binary version of the module, not requiring the above build or
+runtime prerequisites, simply using:
+
+.. code-block:: console
+
+ $ pip install psycopg2-binary
+
+Make sure to use an up-to-date version of :program:`pip` (you can upgrade it
+using something like ``pip install -U pip``)
+
+.. __: PyPI-binary_
+.. _PyPI-binary: https://pypi.python.org/pypi/psycopg2-binary/
+.. _wheel: http://pythonwheels.com/
+
+.. note::
+
+ The binary packages come with their own versions of a few C libraries,
+ among which ``libpq`` and ``libssl``, which will be used regardless of other
+ libraries available on the client: upgrading the system libraries will not
+ upgrade the libraries used by `!psycopg2`. Please build `!psycopg2` from
+ source if you want to maintain binary upgradeability.
+
+.. warning::
+
+ The `!psycopg2` wheel package comes packaged, among the others, with its
+ own ``libssl`` binary. This may create conflicts with other extension
+ modules binding with ``libssl`` as well, for instance with the Python
+ `ssl` module: in some cases, under concurrency, the interaction between
+ the two libraries may result in a segfault. In case of doubts you are
+ advised to use a package built from source.
+
+
+
+.. index::
+ single: Install; disable wheel
+ single: Wheel; disable
+
+.. _disable-wheel:
+
+Disabling wheel packages for Psycopg 2.7
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In version 2.7.x, `pip install psycopg2` would have tried to install the wheel
+binary package of Psycopg. Because of the problems the wheel package have
+displayed, `psycopg2-binary` has become a separate package, and from 2.8 it
+has become the only way to install the binary package.
+
+If you are using psycopg 2.7 and you want to disable the use of wheel binary
+packages, relying on the system system libraries available on your client, you
+can use the :command:`pip` |--no-binary option|__, e.g.:
+
+.. code-block:: console
+
+ $ pip install --no-binary :all: psycopg2
+
+.. |--no-binary option| replace:: ``--no-binary`` option
+.. __: https://pip.pypa.io/en/stable/reference/pip_install/#install-no-binary
+
+which can be specified in your :file:`requirements.txt` files too, e.g. use:
+
+.. code-block:: none
+
+ psycopg2>=2.7,<2.8 --no-binary psycopg2
+
+to use the last bugfix release of the `!psycopg2` 2.7 package, specifying to
+always compile it from source. Of course in this case you will have to meet
+the :ref:`build prerequisites <build-prerequisites>`.
+
+
+
+.. index::
single: setup.py
single: setup.cfg
Non-standard builds
-^^^^^^^^^^^^^^^^^^^
+-------------------
If you have less standard requirements such as:
@@ -225,7 +244,7 @@ order to create a debug package:
- Edit the ``setup.cfg`` file adding the ``PSYCOPG_DEBUG`` flag to the
``define`` option.
-- :ref:`Compile and install <source-package>` the package.
+- :ref:`Compile and install <build-prerequisites>` the package.
- Set the :envvar:`PSYCOPG_DEBUG` environment variable:
@@ -250,11 +269,11 @@ Running the test suite
----------------------
Once `!psycopg2` is installed you can run the test suite to verify it is
-working correctly. You can run:
+working correctly. From the source directory, you can run:
.. code-block:: console
- $ python -c "from psycopg2 import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
+ $ python -c "import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
The tests run against a database called ``psycopg2_test`` on UNIX socket and
the standard port. You can configure a different database to run the test by
diff --git a/doc/src/pool.rst b/doc/src/pool.rst
index 32bca54..38cd08f 100644
--- a/doc/src/pool.rst
+++ b/doc/src/pool.rst
@@ -24,13 +24,18 @@ directly in the client application.
.. method:: getconn(key=None)
- Get a free connection and assign it to *key* if not `!None`.
+ Get a free connection from the pool.
+
+ The *key* parameter is optional: if used, the connection will be
+ associated to the key and calling `!getconn()` with the same key again
+ will return the same connection.
.. method:: putconn(conn, key=None, close=False)
Put away a connection.
If *close* is `!True`, discard the connection from the pool.
+ *key* should be used consistently with `getconn()`.
.. method:: closeall
@@ -57,8 +62,7 @@ be used.
.. autoclass:: PersistentConnectionPool
- .. note::
+ .. note::
This pool class is mostly designed to interact with Zope and probably
not useful in generic applications.
-
diff --git a/doc/src/tools/lib/dbapi_extension.py b/doc/src/tools/lib/dbapi_extension.py
index cb3fec4..23d9165 100755
--- a/doc/src/tools/lib/dbapi_extension.py
+++ b/doc/src/tools/lib/dbapi_extension.py
@@ -12,7 +12,7 @@
from docutils import nodes
from sphinx.locale import _
-from sphinx.util.compat import Directive, make_admonition
+from docutils.parsers.rst import Directive
class extension_node(nodes.Admonition, nodes.Element): pass
@@ -29,12 +29,11 @@ class Extension(Directive):
option_spec = {}
def run(self):
- nodes = make_admonition(extension_node,
- self.name, [_('DB API extension')], self.options,
- self.content, self.lineno, self.content_offset,
- self.block_text, self.state, self.state_machine)
- nodes[0]['classes'].append('dbapi-extension')
- return nodes
+ node = extension_node('\n'.join(self.content))
+ node += nodes.title(_('DB API extension'), _('DB API extension'))
+ self.state.nested_parse(self.content, self.content_offset, node)
+ node['classes'].append('dbapi-extension')
+ return [node]
def visit_extension_node(self, node):
@@ -50,4 +49,3 @@ def setup(app):
text=(visit_extension_node, depart_extension_node))
app.add_directive('extension', Extension)
-
diff --git a/doc/src/tools/lib/sql_role.py b/doc/src/tools/lib/sql_role.py
index 8fb8ab8..43347b4 100644
--- a/doc/src/tools/lib/sql_role.py
+++ b/doc/src/tools/lib/sql_role.py
@@ -12,10 +12,9 @@ from docutils import nodes, utils
from docutils.parsers.rst import roles
def sql_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
- text = utils.unescape(text)
+ text = utils.unescape(text)
options['classes'] = ['sql']
return [nodes.literal(rawtext, text, **options)], []
-
+
def setup(app):
roles.register_local_role('sql', sql_role)
-
diff --git a/doc/src/tools/lib/ticket_role.py b/doc/src/tools/lib/ticket_role.py
index d8ded22..0ee3d63 100644
--- a/doc/src/tools/lib/ticket_role.py
+++ b/doc/src/tools/lib/ticket_role.py
@@ -56,4 +56,3 @@ def setup(app):
app.add_config_value('ticket_remap_offset', None, 'env')
app.add_role('ticket', ticket_role)
app.add_role('tickets', ticket_role)
-
diff --git a/doc/src/tools/stitch_text.py b/doc/src/tools/stitch_text.py
index c9ed99a..e026622 100755
--- a/doc/src/tools/stitch_text.py
+++ b/doc/src/tools/stitch_text.py
@@ -5,6 +5,7 @@
import os
import sys
+
def main():
if len(sys.argv) != 3:
sys.stderr.write("usage: %s index.rst text-dir\n")
@@ -17,23 +18,20 @@ def main():
return 0
+
def iter_file_base(fn):
f = open(fn)
- if sys.version_info[0] >= 3:
- have_line = iter(f).__next__
- else:
- have_line = iter(f).next
- while not have_line().startswith('.. toctree'):
+ while not next(f).startswith('.. toctree'):
pass
- while have_line().strip().startswith(':'):
+ while next(f).strip().startswith(':'):
pass
yield os.path.splitext(os.path.basename(fn))[0]
n = 0
while True:
- line = have_line()
+ line = next(f)
if line.isspace():
continue
if line.startswith(".."):
@@ -47,6 +45,7 @@ def iter_file_base(fn):
# maybe format changed?
raise Exception("Not enough files found. Format change in index.rst?")
+
def emit(basename, txt_dir):
f = open(os.path.join(txt_dir, basename + ".txt"))
for line in f:
@@ -57,7 +56,6 @@ def emit(basename, txt_dir):
# some space between sections
sys.stdout.write("\n\n")
-
+
if __name__ == '__main__':
sys.exit(main())
-
diff --git a/doc/src/tz.rst b/doc/src/tz.rst
index 6e2e981..06333f8 100644
--- a/doc/src/tz.rst
+++ b/doc/src/tz.rst
@@ -8,9 +8,8 @@
This module holds two different tzinfo implementations that can be used as the
`tzinfo` argument to `~datetime.datetime` constructors, directly passed to
Psycopg functions or used to set the `cursor.tzinfo_factory` attribute in
-cursors.
+cursors.
.. autoclass:: psycopg2.tz.FixedOffsetTimezone
.. autoclass:: psycopg2.tz.LocalTimezone
-
diff --git a/doc/src/usage.rst b/doc/src/usage.rst
index 660f290..db8674c 100644
--- a/doc/src/usage.rst
+++ b/doc/src/usage.rst
@@ -48,7 +48,7 @@ The main entry points of Psycopg are:
- The class `connection` encapsulates a database session. It allows to:
- - create new `cursor`\s using the `~connection.cursor()` method to
+ - create new `cursor` instances using the `~connection.cursor()` method to
execute database commands and queries,
- terminate transactions using the methods `~connection.commit()` or
@@ -73,70 +73,97 @@ The main entry points of Psycopg are:
Passing parameters to SQL queries
---------------------------------
-Psycopg casts Python variables to SQL literals by type. Many standard Python types
-are already `adapted to the correct SQL representation`__.
+Psycopg converts Python variables to SQL values using their types: the Python
+type determines the function used to convert the object into a string
+representation suitable for PostgreSQL. Many standard Python types are
+already `adapted to the correct SQL representation`__.
.. __: python-types-adaptation_
-Example: the Python function call::
+Passing parameters to an SQL statement happens in functions such as
+`cursor.execute()` by using ``%s`` placeholders in the SQL statement, and
+passing a sequence of values as the second argument of the function. For
+example the Python function call::
- >>> cur.execute(
- ... """INSERT INTO some_table (an_int, a_date, a_string)
- ... VALUES (%s, %s, %s);""",
+ >>> cur.execute("""
+ ... INSERT INTO some_table (an_int, a_date, a_string)
+ ... VALUES (%s, %s, %s);
+ ... """,
... (10, datetime.date(2005, 11, 18), "O'Reilly"))
-is converted into the SQL command::
+is converted into a SQL command similar to:
+
+.. code-block:: sql
INSERT INTO some_table (an_int, a_date, a_string)
- VALUES (10, '2005-11-18', 'O''Reilly');
+ VALUES (10, '2005-11-18', 'O''Reilly');
-Named arguments are supported too using :samp:`%({name})s` placeholders.
-Using named arguments the values can be passed to the query in any order and
-many placeholders can use the same values::
+Named arguments are supported too using :samp:`%({name})s` placeholders in the
+query and specifying the values into a mapping. Using named arguments allows
+to specify the values in any order and to repeat the same value in several
+places in the query::
- >>> cur.execute(
- ... """INSERT INTO some_table (an_int, a_date, another_date, a_string)
- ... VALUES (%(int)s, %(date)s, %(date)s, %(str)s);""",
+ >>> cur.execute("""
+ ... INSERT INTO some_table (an_int, a_date, another_date, a_string)
+ ... VALUES (%(int)s, %(date)s, %(date)s, %(str)s);
+ ... """,
... {'int': 10, 'str': "O'Reilly", 'date': datetime.date(2005, 11, 18)})
+Using characters ``%``, ``(``, ``)`` in the argument names is not supported.
+
When parameters are used, in order to include a literal ``%`` in the query you
-can use the ``%%`` string. Using characters ``%``, ``(``, ``)`` in the
-argument names is not supported.
+can use the ``%%`` string::
+
+ >>> cur.execute("SELECT (%s % 2) = 0 AS even", (10,)) # WRONG
+ >>> cur.execute("SELECT (%s %% 2) = 0 AS even", (10,)) # correct
While the mechanism resembles regular Python strings manipulation, there are a
few subtle differences you should care about when passing parameters to a
-query:
+query.
-- The Python string operator ``%`` is not used: the `~cursor.execute()`
+- The Python string operator ``%`` *must not be used*: the `~cursor.execute()`
method accepts a tuple or dictionary of values as second parameter.
- |sql-warn|__.
+ |sql-warn|__:
.. |sql-warn| replace:: **Never** use ``%`` or ``+`` to merge values
into queries
.. __: sql-injection_
-- The variables placeholder must *always be a* ``%s``, even if a different
- placeholder (such as a ``%d`` for integers or ``%f`` for floats) may look
- more appropriate::
-
- >>> cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG
- >>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct
+ >>> cur.execute("INSERT INTO numbers VALUES (%s, %s)" % (10, 20)) # WRONG
+ >>> cur.execute("INSERT INTO numbers VALUES (%s, %s)", (10, 20)) # correct
- For positional variables binding, *the second argument must always be a
- sequence*, even if it contains a single variable. And remember that Python
- requires a comma to create a single element tuple::
+ sequence*, even if it contains a single variable (remember that Python
+ requires a comma to create a single element tuple)::
>>> cur.execute("INSERT INTO foo VALUES (%s)", "bar") # WRONG
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar")) # WRONG
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
>>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct
+- The placeholder *must not be quoted*. Psycopg will add quotes where needed::
+
+ >>> cur.execute("INSERT INTO numbers VALUES ('%s')", (10,)) # WRONG
+ >>> cur.execute("INSERT INTO numbers VALUES (%s)", (10,)) # correct
+
+- The variables placeholder *must always be a* ``%s``, even if a different
+ placeholder (such as a ``%d`` for integers or ``%f`` for floats) may look
+ more appropriate::
+
+ >>> cur.execute("INSERT INTO numbers VALUES (%d)", (10,)) # WRONG
+ >>> cur.execute("INSERT INTO numbers VALUES (%s)", (10,)) # correct
+
- Only query values should be bound via this method: it shouldn't be used to
- merge table or field names to the query. If you need to generate dynamically
- an SQL query (for instance choosing dynamically a table name) you can use
- the facilities provided by the `psycopg2.sql` module.
+ merge table or field names to the query (Psycopg will try quoting the table
+ name as a string value, generating invalid SQL). If you need to generate
+ dynamically SQL queries (for instance choosing dynamically a table name)
+ you can use the facilities provided by the `psycopg2.sql` module::
+ >>> cur.execute("INSERT INTO %s VALUES (%s)", ('numbers', 10)) # WRONG
+ >>> cur.execute( # correct
+ ... SQL("INSERT INTO {} VALUES (%s)").format(Identifier('numbers')),
+ ... (10,))
.. index:: Security, SQL injection
@@ -430,14 +457,12 @@ the connection or globally: see the function
Binary adaptation
^^^^^^^^^^^^^^^^^
-Python types representing binary objects are converted into
-PostgreSQL binary string syntax, suitable for :sql:`bytea` fields. Such
-types are `buffer` (only available in Python 2), `memoryview` (available
-from Python 2.7), `bytearray` (available from Python 2.6) and `bytes`
-(only from Python 3: the name is available from Python 2.6 but it's only an
-alias for the type `!str`). Any object implementing the `Revised Buffer
-Protocol`__ should be usable as binary type where the protocol is supported
-(i.e. from Python 2.6). Received data is returned as `!buffer` (in Python 2)
+Python types representing binary objects are converted into PostgreSQL binary
+string syntax, suitable for :sql:`bytea` fields. Such types are `buffer`
+(only available in Python 2), `memoryview`, `bytearray`, and `bytes` (only in
+Python 3: the name is available in Python 2 but it's only an alias for the
+type `!str`). Any object implementing the `Revised Buffer Protocol`__ should
+be usable as binary type. Received data is returned as `!buffer` (in Python 2)
or `!memoryview` (in Python 3).
.. __: http://www.python.org/dev/peps/pep-3118/
@@ -535,8 +560,7 @@ rounded to the nearest minute, with an error of up to 30 seconds.
.. versionchanged:: 2.2.2
timezones with seconds are supported (with rounding). Previously such
- timezones raised an error. In order to deal with them in previous
- versions use `psycopg2.extras.register_tstz_w_secs()`.
+ timezones raised an error.
.. index::
@@ -792,7 +816,9 @@ lifetime extends well after `~connection.commit()`, calling
It is also possible to use a named cursor to consume a cursor created
in some other way than using the |DECLARE| executed by
`~cursor.execute()`. For example, you may have a PL/pgSQL function
- returning a cursor::
+ returning a cursor:
+
+ .. code-block:: postgres
CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS $$
BEGIN
@@ -990,4 +1016,3 @@ For further details see the documentation for the above methods.
.. __: http://www.opengroup.org/bookstore/catalog/c193.htm
.. __: http://jdbc.postgresql.org/
-