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
|
Connections are thread safe and can be shared among many thread. See
|
||||||
:ref:`thread-safety` for details.
|
:ref:`thread-safety` for details.
|
||||||
|
|
||||||
.. method:: cursor([name] [, cursor_factory])
|
.. method:: cursor([name] [, cursor_factory] [, withhold])
|
||||||
|
|
||||||
Return a new `cursor` object using the connection.
|
Return a new `cursor` object using the connection.
|
||||||
|
|
||||||
If *name* is specified, the returned cursor will be a :ref:`server
|
If *name* is specified, the returned cursor will be a :ref:`server
|
||||||
side cursor <server-side-cursors>` (also known as *named cursor*).
|
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
|
The name can be a string not valid as a PostgreSQL identifier: for
|
||||||
example it may start with a digit and contain non-alphanumeric
|
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|.
|
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*()`
|
.. |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;
|
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.
|
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| replace:: :sql:`DECLARE`
|
||||||
.. _DECLARE: http://www.postgresql.org/docs/9.0/static/sql-declare.html
|
.. _DECLARE: http://www.postgresql.org/docs/9.0/static/sql-declare.html
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
/* cursor method - allocate a new cursor */
|
/* cursor method - allocate a new cursor */
|
||||||
|
|
||||||
#define psyco_conn_cursor_doc \
|
#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" \
|
"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" \
|
"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" \
|
"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 != NULL) {
|
||||||
if (withhold == Py_True && name == NULL) {
|
if (PyObject_IsTrue(withhold) && name == NULL) {
|
||||||
PyErr_SetString(ProgrammingError,
|
PyErr_SetString(ProgrammingError,
|
||||||
"'withhold=True can be specified only for named cursors");
|
"'withhold=True can be specified only for named cursors");
|
||||||
return NULL;
|
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);
|
EXC_IF_CONN_CLOSED(self);
|
||||||
|
@ -109,7 +104,7 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withhold == Py_True)
|
if (withhold != NULL && PyObject_IsTrue(withhold))
|
||||||
((cursorObject*)obj)->withhold = 1;
|
((cursorObject*)obj)->withhold = 1;
|
||||||
|
|
||||||
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
Dprintf("psyco_conn_cursor: new cursor at %p: refcnt = "
|
||||||
|
|
|
@ -161,8 +161,6 @@ class CursorTests(unittest.TestCase):
|
||||||
def test_withhold(self):
|
def test_withhold(self):
|
||||||
self.assertRaises(psycopg2.ProgrammingError, self.conn.cursor,
|
self.assertRaises(psycopg2.ProgrammingError, self.conn.cursor,
|
||||||
withhold=True)
|
withhold=True)
|
||||||
self.assertRaises(psycopg2.ProgrammingError, self.conn.cursor,
|
|
||||||
"NAME", withhold="")
|
|
||||||
|
|
||||||
curs = self.conn.cursor()
|
curs = self.conn.cursor()
|
||||||
curs.execute("drop table if exists withhold")
|
curs.execute("drop table if exists withhold")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user