From 50f5daef8bc62024d76bf007d2763cfb6fd1db41 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 18 Feb 2010 03:51:17 +0000 Subject: [PATCH] Added FAQ section to the documentation. --- doc/src/_static/psycopg.css | 3 ++ doc/src/connection.rst | 11 ++--- doc/src/extensions.rst | 6 ++- doc/src/faq.rst | 81 +++++++++++++++++++++++++++++++++++++ doc/src/index.rst | 1 + doc/src/usage.rst | 12 +++--- 6 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 doc/src/faq.rst diff --git a/doc/src/_static/psycopg.css b/doc/src/_static/psycopg.css index 5cb9284e..c4a2af65 100644 --- a/doc/src/_static/psycopg.css +++ b/doc/src/_static/psycopg.css @@ -23,3 +23,6 @@ a > tt.sql:hover { text-decoration: underline; } +dl.faq dt { + font-weight: bold; +} diff --git a/doc/src/connection.rst b/doc/src/connection.rst index 08d463a4..6addc033 100644 --- a/doc/src/connection.rst +++ b/doc/src/connection.rst @@ -134,14 +134,15 @@ The ``connection`` class the module :mod:`psycopg2.extensions`: see :ref:`isolation-level-constants` for the available values. - The default level is :sql:`READ COMMITTED`: in this level a transaction - is automatically started every time a database command is executed. If - you want an *autocommit* mode, switch to - :const:`~psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT` - before executing any command:: + The default level is :sql:`READ COMMITTED`: at this level a + transaction is automatically started the first time a database command + is executed. If you want an *autocommit* mode, switch to + :const:`~psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT` before + executing any command:: >>> conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) + See also :ref:`transactions-control`. .. index:: pair: Client; Encoding diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst index 99479018..ed34f614 100644 --- a/doc/src/extensions.rst +++ b/doc/src/extensions.rst @@ -321,11 +321,13 @@ set to one of the following constants: No transaction is started when command are issued and no :meth:`~connection.commit` or :meth:`~connection.rollback` is required. - Some PostgreSQL command such as :sql:`CREATE DATABASE` can't run into a - transaction: to run such command use:: + Some PostgreSQL command such as :sql:`CREATE DATABASE` or :sql:`VACUUM` + can't run into a transaction: to run such command use:: >>> conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) + See also :ref:`transactions-control`. + .. data:: ISOLATION_LEVEL_READ_UNCOMMITTED The :sql:`READ UNCOMMITTED` isolation level is defined in the SQL standard but not available in diff --git a/doc/src/faq.rst b/doc/src/faq.rst new file mode 100644 index 00000000..53f5b27c --- /dev/null +++ b/doc/src/faq.rst @@ -0,0 +1,81 @@ +Frequently Asked Questions +========================== + +.. sectionauthor:: Daniele Varrazzo + +Here are a few gotchas you may encounter using :mod:`psycopg2`. Feel free to +suggest new entries! + + +.. cssclass:: faq + +Why does :mod:`!psycopg2` leave database sessions "idle in transaction"? + Psycopg normally starts a new transaction the first time a query is + executed, e.g. calling :meth:`cursor.execute`, even if the command is a + :sql:`SELECT`. The transaction is not closed until an explicit + :meth:`~connection.commit` or :meth:`~connection.rollback`. + + If you are writing a long-living program, you should probably ensure to + call one of the transaction closing methods before leaving the connection + unused for a long time (which may also be a few seconds, depending on the + concurrency level in your database). Alternatively you can use a + connection in :ref:`autocommit ` mode to avoid a new + transaction to be started at the first command. + +Why does :meth:`!cursor.execute` raise the exception *can't adapt*? + Psycopg converts Python objects in a SQL string representation by looking + at the object class. The exception is raised when you are trying to pass + as query parameter an object for which there is no adapter registered for + its class. See :ref:`adapting-new-types` for informations. + +I can't pass an integer or a float parameter to my query: it says *a number is required*, but *it is* a number! + In your query string, you always have to use ``%s`` placeholders, + event when passing a number. All Python objects are converted by Psycopg + in their SQL representation, so they get passed to the query as strings. + See :ref:`query-parameters`. :: + + >>> cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG + >>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct + +I try to execute a query but it fails with the error *not all arguments converted during string formatting* (or *object does not support indexing*). Why? + Psycopg always require positional arguments to be passed as a tuple, even + when the query takes a single parameter. And remember that to make a + single item tuple in Python you need a comma! See :ref:`query-parameters`. + :: + + >>> 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 + +I receive the error *current transaction is aborted, commands ignored until end of transaction block* and can't do anything else! + There was a problem *in the previous* command to the database, which + resulted in an error. The database will not recover automatically from + this condition: you must run a :meth:`~connection.rollback` before sending + new commands to the session (if this seems too harsh, remember that + PostgreSQL supports nested transactions using the |SAVEPOINT|_ command). + + .. |SAVEPOINT| replace:: :sql:`SAVEPOINT` + .. _SAVEPOINT: http://www.postgresql.org/docs/8.4/static/sql-savepoint.html + +Why do i get the error *current transaction is aborted, commands ignored until end of transaction block* when I use :mod:`!multiprocessing` (or any other forking system) and not when use :mod:`!threading`? + Psycopg's connections can't be shared across processes (but are thread + safe). If you are forking the Python process ensure to create a new + connection in each forked child. + +My database is Unicode, but I receive all the strings as UTF-8 :class:`str`. Can I receive :class:`unicode` objects instead? + The following magic formula will do the trick:: + + psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) + psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) + + See :ref:`unicode-handling` for the gory details. + +I can't compile :mod:`!psycopg2`: the compiler says *error: Python.h: No such file or directory*. What am I missing? + You need to install a Python development package: it is usually called + ``python-dev``. + +I can't compile :mod:`!psycopg2`: the compiler says *error: libpq-fe.h: No such file or directory*. What am I missing? + You need to install the development version of the libpq: the package is + usually called ``libpq-dev``. + + diff --git a/doc/src/index.rst b/doc/src/index.rst index f8529a32..247b5013 100644 --- a/doc/src/index.rst +++ b/doc/src/index.rst @@ -40,6 +40,7 @@ PostgreSQL arrays. tz extras errorcodes + faq .. ifconfig:: builder != 'text' diff --git a/doc/src/usage.rst b/doc/src/usage.rst index 413580e6..74f538e1 100644 --- a/doc/src/usage.rst +++ b/doc/src/usage.rst @@ -118,9 +118,11 @@ query: >>> cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct - For positional variables binding, *the second argument must always be a - tuple*, even if it contains a single variable:: + tuple*, even if it contains a single variable. And 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 - Only variable values should be bound via this method: it shouldn't be used @@ -374,7 +376,7 @@ Transactions control -------------------- In Psycopg transactions are handled by the :class:`connection` class. By -default, every time a command is sent to the database (using one of the +default, the first time a command is sent to the database (using one of the :class:`cursor`\ s created by the connection), a new transaction is created. The following database commands will be executed in the context of the same transaction -- not only the commands issued by the first cursor, but the ones @@ -391,9 +393,9 @@ will result in an implicit :meth:`!rollback` call. It is possible to set the connection in *autocommit* mode: this way all the commands executed will be immediately committed and no rollback is possible. A -few commands (e.g. :sql:`CREATE DATABASE`) require to be run outside any -transaction: in order to be able to run these commands from Psycopg, the -session must be in autocommit mode. Read the documentation for +few commands (e.g. :sql:`CREATE DATABASE`, :sql:`VACUUM`...) require to be run +outside any transaction: in order to be able to run these commands from +Psycopg, the session must be in autocommit mode. Read the documentation for :meth:`connection.set_isolation_level` to know how to change the commit mode.