mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-07 12:50:32 +03:00
WITH HOLD documentation a argument parsing changes
Now any true value will do for the withhold parameter.
This commit is contained in:
parent
a59d88c703
commit
880aa07a58
|
@ -21,13 +21,16 @@ The ``connection`` class
|
|||
Connections are thread safe and can be shared among many thread. See
|
||||
:ref:`thread-safety` for details.
|
||||
|
||||
.. method:: cursor([name] [, cursor_factory])
|
||||
.. method:: cursor([name] [, cursor_factory] [, withhold])
|
||||
|
||||
Return a new `cursor` object using the connection.
|
||||
|
||||
If *name* is specified, the returned cursor will be a :ref:`server
|
||||
side cursor <server-side-cursors>` (also known as *named cursor*).
|
||||
Otherwise it will be a regular *client side* cursor.
|
||||
Otherwise it will be a regular *client side* cursor. By default a
|
||||
:sql:`WITHOUT HOLD` cursor is created; to create a :sql:`WITH HOLD`
|
||||
cursor, pass a `!True` value as the *withhold* parameter. See
|
||||
:ref:`server-side-cursors`.
|
||||
|
||||
The name can be a string not valid as a PostgreSQL identifier: for
|
||||
example it may start with a digit and contain non-alphanumeric
|
||||
|
|
|
@ -114,6 +114,19 @@ The ``cursor`` class
|
|||
The `name` attribute is a Psycopg extension to the |DBAPI|.
|
||||
|
||||
|
||||
.. attribute:: withhold
|
||||
|
||||
Read/write attribute: specifies if a named cursor lifetime should
|
||||
extend outside of the current transaction, i.e., it is possible to
|
||||
fetch from the cursor even after a `commection.commit()` (but not after
|
||||
a `connection.rollback()`). See :ref:`server-side-cursors`
|
||||
|
||||
.. versionadded:: 2.4.3
|
||||
|
||||
.. extension::
|
||||
|
||||
The `name` attribute is a Psycopg extension to the |DBAPI|.
|
||||
|
||||
|
||||
.. |execute*| replace:: `execute*()`
|
||||
|
||||
|
|
|
@ -575,6 +575,19 @@ during the iteration: the default value of 2000 allows to fetch about 100KB
|
|||
per roundtrip assuming records of 10-20 columns of mixed number and strings;
|
||||
you may decrease this value if you are dealing with huge records.
|
||||
|
||||
Named cursors are usually created :sql:`WITHOUT HOLD`, meaning they live only
|
||||
as long as the current transaction. Trying to fetch from a named cursor after
|
||||
a `~connection.commit()` or to create a named cursor when the `connection`
|
||||
transaction isolation level is set to `AUTOCOMMIT` will result in an exception.
|
||||
It is possible to create a :sql:`WITH HOLD` cursor by specifying a `!True`
|
||||
value for the `withhold` parameter to `~connection.cursor()` or by setting the
|
||||
`~cursor.withhold` attribute to `!True` before calling `~cursor.execute()` on
|
||||
the cursor. It is extremely important to always `~cursor.close()` such cursors,
|
||||
otherwise they will continue to hold server-side resources until the connection
|
||||
will be eventually be closed. Also note that while :sql:`WITH HOLD` cursors
|
||||
lifetime extends well after `~connection.commit()`, calling
|
||||
`~connection.rollback()` will automatically close the cursor.
|
||||
|
||||
.. |DECLARE| replace:: :sql:`DECLARE`
|
||||
.. _DECLARE: http://www.postgresql.org/docs/9.0/static/sql-declare.html
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
/* cursor method - allocate a new cursor */
|
||||
|
||||
#define psyco_conn_cursor_doc \
|
||||
"cursor(cursor_factory=extensions.cursor) -- new cursor\n\n" \
|
||||
"cursor(name=None, cursor_factory=extensions.cursor, withhold=None) -- new cursor\n\n" \
|
||||
"Return a new cursor.\n\nThe ``cursor_factory`` argument can be used to\n" \
|
||||
"create non-standard cursors by passing a class different from the\n" \
|
||||
"default. Note that the new class *should* be a sub-class of\n" \
|
||||
|
@ -63,16 +63,11 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
|
|||
}
|
||||
|
||||
if (withhold != NULL) {
|
||||
if (withhold == Py_True && name == NULL) {
|
||||
if (PyObject_IsTrue(withhold) && name == NULL) {
|
||||
PyErr_SetString(ProgrammingError,
|
||||
"'withhold=True can be specified only for named cursors");
|
||||
return NULL;
|
||||
}
|
||||
if (withhold != NULL && withhold != Py_True && withhold != Py_False) {
|
||||
PyErr_SetString(ProgrammingError,
|
||||
"'withhold should be True or False");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXC_IF_CONN_CLOSED(self);
|
||||
|
@ -109,7 +104,7 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (withhold == Py_True)
|
||||
if (withhold != NULL && PyObject_IsTrue(withhold))
|
||||
((cursorObject*)obj)->withhold = 1;
|
||||
|
||||
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
||||
|
|
|
@ -161,8 +161,6 @@ class CursorTests(unittest.TestCase):
|
|||
def test_withhold(self):
|
||||
self.assertRaises(psycopg2.ProgrammingError, self.conn.cursor,
|
||||
withhold=True)
|
||||
self.assertRaises(psycopg2.ProgrammingError, self.conn.cursor,
|
||||
"NAME", withhold="")
|
||||
|
||||
curs = self.conn.cursor()
|
||||
curs.execute("drop table if exists withhold")
|
||||
|
|
Loading…
Reference in New Issue
Block a user