Added optional DB API 2.0 extensions as discussed on the DB SIG.

This commit is contained in:
Marc-André Lemburg 2002-02-04 22:47:07 +00:00
parent b71153a027
commit cdb77a562c
1 changed files with 250 additions and 23 deletions

View File

@ -34,11 +34,11 @@ Introduction
available packages see the Database Topic
Guide at http://www.python.org/topics/database/.
This document describes the Python Database API Specification
2.0. The previous version 1.0 version is still available as
reference, in PEP 248. Package writers are encouraged to use
this version of the specification as basis for new interfaces.
This document describes the Python Database API Specification 2.0
and a set of common optional extensions. The previous version 1.0
version is still available as reference, in PEP 248. Package
writers are encouraged to use this version of the specification as
basis for new interfaces.
Module Interface
@ -192,7 +192,7 @@ Connection Objects
Connection Objects should respond to the following methods:
close()
.close()
Close the connection now (rather than whenever __del__ is
called). The connection will be unusable from this point
@ -204,7 +204,7 @@ Connection Objects
rollback to be performed.
commit()
.commit()
Commit any pending transaction to the database. Note that
if the database supports an auto-commit feature, this must
@ -214,7 +214,7 @@ Connection Objects
Database modules that do not support transactions should
implement this method with void functionality.
rollback()
.rollback()
This method is optional since not all databases provide
transaction support. [3]
@ -225,7 +225,7 @@ Connection Objects
committing the changes first will cause an implicit
rollback to be performed.
cursor()
.cursor()
Return a new Cursor Object using the connection. If the
database does not provide a direct cursor concept, the
@ -247,7 +247,7 @@ Cursor Objects
Cursor Objects should respond to the following methods and
attributes:
description
.description
This read-only attribute is a sequence of 7-item
sequences. Each of these sequences contains information
@ -264,7 +264,7 @@ Cursor Objects
The type_code can be interpreted by comparing it to the
Type Objects specified in the section below.
rowcount
.rowcount
This read-only attribute specifies the number of rows that
the last executeXXX() produced (for DQL statements like
@ -275,7 +275,11 @@ Cursor Objects
performed on the cursor or the rowcount of the last
operation is not determinable by the interface. [7]
callproc(procname[,parameters])
Note: Future versions of the DB API specification could
redefine the latter case to have the object return None
instead of -1.
.callproc(procname[,parameters])
(This method is optional since not all databases provide
stored procedures. [3])
@ -291,14 +295,14 @@ Cursor Objects
output. This must then be made available through the
standard fetchXXX() methods.
close()
.close()
Close the cursor now (rather than whenever __del__ is
called). The cursor will be unusable from this point
forward; an Error (or subclass) exception will be raised
if any operation is attempted with the cursor.
execute(operation[,parameters])
.execute(operation[,parameters])
Prepare and execute a database operation (query or
command). Parameters may be provided as sequence or
@ -326,7 +330,7 @@ Cursor Objects
Return values are not defined.
executemany(operation,seq_of_parameters)
.executemany(operation,seq_of_parameters)
Prepare a database operation (query or command) and then
execute it against all parameter sequences or mappings
@ -348,7 +352,7 @@ Cursor Objects
Return values are not defined.
fetchone()
.fetchone()
Fetch the next row of a query result set, returning a
single sequence, or None when no more data is
@ -382,7 +386,7 @@ Cursor Objects
parameter is used, then it is best for it to retain the
same value from one fetchmany() call to the next.
fetchall()
.fetchall()
Fetch all (remaining) rows of a query result, returning
them as a sequence of sequences (e.g. a list of tuples).
@ -393,7 +397,7 @@ Cursor Objects
call to executeXXX() did not produce any result set or no
call was issued yet.
nextset()
.nextset()
(This method is optional since not all databases support
multiple result sets. [3])
@ -411,7 +415,7 @@ Cursor Objects
call to executeXXX() did not produce any result set or no
call was issued yet.
arraysize
.arraysize
This read/write attribute specifies the number of rows to
fetch at a time with fetchmany(). It defaults to 1 meaning
@ -422,7 +426,7 @@ Cursor Objects
database a single row at a time. It may also be used in
the implementation of executemany().
setinputsizes(sizes)
.setinputsizes(sizes)
This can be used before a call to executeXXX() to
predefine memory areas for the operation's parameters.
@ -441,7 +445,7 @@ Cursor Objects
Implementations are free to have this method do nothing
and users are free to not use it.
setoutputsize(size[,column])
.setoutputsize(size[,column])
Set a column buffer size for fetches of large columns
(e.g. LONGs, BLOBs, etc.). The column is specified as an
@ -553,7 +557,8 @@ Type Objects and Constructors
Note: Usage of Unix ticks for database interfacing can cause
troubles because of the limited date range they cover.
Implementation Hints
Implementation Hints for Module Authors
* The preferred object types for the date/time objects are those
defined in the mxDateTime package. It provides all necessary
@ -639,6 +644,222 @@ Implementation Hints
base, NULL) API to create the exception objects.
Optional DB API Extensions
During the lifetime of DB API 2.0, module authors have often
extended their implementations beyond what is required by this DB
API specification. To enhance compatibility and to provide a clean
upgrade path to possible future versions of the specification,
this section defines a set of common extensions to the core DB API
2.0 specification.
As with all DB API optional features, the database module authors
are free to not implement these additional attributes and methods
(using them will then result in an AttributeError) or to raise a
NotSupportedError in case the availability can only be checked at
run-time.
It has been proposed to make usage of these extensions optionally
visible to the programmer by issuing Python warnings through the
Python warning framework. To make this feature useful, the warning
messages must be standardized in order to be able to mask them. These
standard messages are referred to below as "Warning Message".
Cursor Attribute .rownumber
This read-only attribute should provide the current 0-based
index of the cursor in the result set or None if the index cannot
be determined.
The index can be seen as index of the cursor in a sequence (the
result set). The next fetch operation will fetch the row
indexed by .rownumber in that sequence.
Warning Message: "DB-API extension cursor.rownumber used"
Connection Attributes .Error, .ProgrammingError, etc.
All exception classes defined by the DB API standard should be
exposed on the Connection objects are attributes (in addition
to being available at module scope).
These attributes simplify error handling in multi-connection
environments.
Warning Message: "DB-API extension connection.<exception> used"
Cursor Attributes .connection
This read-only attribute return a reference to the Connection
object on which the cursor was created.
The attribute simplifies writing polymorph code in
multi-connection environments.
Warning Message: "DB-API extension cursor.connection used"
Cursor Method .scroll(value[,mode='relative'])
Scroll the cursor in the result set to a new position according
to mode.
If mode is 'relative' (default), value is taken as offset to
the current position in the result set, if set to 'absolute',
value states an absolute target position.
An IndexError should be raised in case a scroll operation would
leave the result set. In this case, the cursor position is left
undefined (ideal would be to not move the cursor at all).
Note: This method should use native scrollable cursors, if
available , or revert to an emulation for forward-only
scrollable cursors. The method may raise NotSupportedErrors to
signal that a specific operation is not supported by the
database (e.g. backward scrolling).
Warning Message: "DB-API extension cursor.scroll() used"
Cursor Attribute .messages
This is a Python list object to which the interface appends
tuples (exception class, exception value) for all messages
which the interfaces receives from the underlying database for
this cursor.
The list is cleared by all standard cursor methods calls (prior
to executing the call) except for the .fetchXXX() calls
automatically to avoid excessive memory usage and can also be
cleared by executing "del cursor.messages[:]".
All error and warning messages generated by the database are
placed into this list, so checking the list allows the user to
verify correct operation of the method calls.
The aim of this attribute is to eliminate the need for a
Warning exception which often causes problems (some warnings
really only have informational character).
Warning Message: "DB-API extension cursor.messages used"
Connection Attribute .messages
Same as cursor.messages except that the messages in the list
are connection oriented.
The list is cleared automatically by all standard connection
methods calls (prior to executing the call) to avoid excessive
memory usage and can also be cleared by executing "del
connection.messages[:]".
Warning Message: "DB-API extension connection.messages used"
Cursor Method .next()
Return the next row from the currently executing SQL statement
using the same semantics as .fetchone(). A StopIteration
exception is raised when the result set is exhausted for Python
versions 2.2 and later. Previous versions don't have the
StopIteration exception and so the method should raise an
IndexError instead.
Warning Message: "DB-API extension cursor.next() used"
Cursor Method .__iter__()
Return self to make cursors compatible to the iteration protocol.
Warning Message: "DB-API extension cursor.__iter__() used"
Cursor Attribute .lastrowid
This read-only attribute provides the rowid of the last
modified row (most databases return a rowid only when a single
INSERT operation is performed). If the operation does not set
a rowid or if the database does not support rowids, this
attribute should be set to None.
The semantics of .lastrowid are undefined in case the last
executed statement modified more than one row, e.g. when
using INSERT with .executemany().
Warning Message: "DB-API extension cursor.lastrowid used"
Optional Error Handling Extension
The core DB API specification only introduces a set of exceptions
which can be raised to report errors to the user. In some cases,
exceptions may be too disruptive for the flow of a program or even
render execution impossible.
For these cases and in order to simplify error handling when
dealing with databases, database module authors may choose to
implement user defineable error handlers. This section describes a
standard way of defining these error handlers.
Cursor/Connection Attribute .errorhandler
Read/write attribute which references an error handler to call
in case an error condition is met.
The handler must be a Python callable taking the following
arguments: errorhandler(connection, cursor, errorclass,
errorvalue) where connection is a reference to the connection
on which the cursor operates, cursor a reference to the cursor
(or None in case the error does not apply to a cursor),
errorclass is an error class which to instantiate using
errorvalue as construction argument.
The standard error handler should add the error information to
the appropriate .messages attribute (connection.messages or
cursor.messages) and raise the exception defined by the given
errorclass and errorvalue parameters.
If no errorhandler is set (the attribute is None), the standard
error handling scheme as outlined above, should be applied.
Warning Message: "DB-API extension .errorhandler used"
Cursors should inherit the .errorhandler setting from their
connection objects at cursor creation time.
Frequently Asked Questions
The database SIG often sees reoccurring questions about the DB API
specification. This section covers some of the issues people
sometimes have with the specification.
Question:
How can I construct a dictionary out of the tuples returned by
.fetchxxx():
Answer:
There are several existing tools available which provide
helpers for this task. Most of them use the approach of using
the column names defined in the cursor attribute .description
as basis for the keys in the row dictionary.
Note that the reason for not extending the DB API specification
to also support dictionary return values for the .fetchxxx()
methods is that this approach has several drawbacks:
* Some databases don't support case-sensitive column names or
auto-convert them to all lowercase or all uppercase
characters.
* Columns in the result set which are generated by the query
(e.g. using SQL functions) don't map to table column names
and databases usually generate names for these columns in a
very database specific way.
As a result, accessing the columns through dictionary keys
varies between databases and makes writing portable code
impossible.
Major Changes from Version 1.0 to Version 2.0
The Python Database API 2.0 introduces a few major changes
@ -677,12 +898,18 @@ Major Changes from Version 1.0 to Version 2.0
exception layout defined in this specification by
subclassing the defined exception classes.
Post-publishing additions to the DB API 2.0 specification:
* Additional optional DB API extensions to the set of
core functionality were specified.
Open Issues
Although the version 2.0 specification clarifies a lot of
questions that were left open in the 1.0 version, there are still
some remaining issues:
some remaining issues which should be addressed in future
versions:
* Define a useful return value for .nextset() for the case where
a new result set is available.