<!DOCTYPE linuxdoc system>
<article>
<title>MySQLdb: a Python interface for MySQL
<author>Andy Dustman
<date>$Id: MySQLdb.sgml,v 1.8 2002/07/01 03:36:17 adustman Exp $

<abstract>MySQLdb is an thread-compatible interface to the popular
MySQL database server that provides the Python database API.

<sect>Introduction 

<P>This module should be <ref id="MySQLmodule" name="mostly
compatible"> with an older interface written by Joe Skinner and
others. However, the older version is a) not thread-friendly (database
operations could cause all other threads to block), b) written for
MySQL 3.21 (does not compile against newer versions without patches),
c) apparently not actively maintained. MySQLdb is a completely new
module, distributed free of charge under the GNU Public License.

<p>
<sect1>Platforms
<p>
<sect2>Linux/UNIX
<p>
This module is developed on RedHat Linux (currently 7.1) for Intel. It
should build without much trouble on most platforms by using the
<tt/setup.py/ script.  Supposedly it builds on MacOS X.  Be aware that
you need the Distutils package which comes with Python 2.0. If you
don't have it (i.e. you have Python 1.5.2), you can find it over at
<htmlurl url="http://www.python.org/" name="www.python.org">.

<sect2>Windows (3.11, 95, 98, NT, 2000, CE, BSOD, XYZ, etc.)
<p>
Windows is <em/not/ a supported platform.  However, the <tt/setup.py/
script reportedly gets the job done.  There is probably a link on the
web page for getting a precompiled Windows installer from someone or
other.  Be aware that this is a user-contributed package; the author
cannot help you with compiling and running under Windows.
<sect1>Python
<p>
MySQLdb requires Python 1.5.2 or newer. Earlier versions will not
work, because support for C <tt/long long/ is required by MySQL.  If
you have an earlier version of Python, upgrade to 1.5.2 or beyond.
Current development is done with Python 2.2.1, but Python 1.5.2 will be
supported for the forseeable future.

<sect1>MySQL
<p>
<sect2>MySQL-3.22
<p>
Only versions 3.22.32 and up are guaranteed to work. Some older
versions may work; if you have an older version you should seriously
consider upgrading to get the bug fixes and particularly the security
updates.

MySQL-3.22 seems to have a problem trying to insert <tt/TIME/ values
with fractional seconds. Values like 12:56:13.00 are returned as
344:13:00, apparently interpreting the original input as 12 days, 56
hours, 13 minutes, 0 seconds. (12 days and 56 hours is 344 hours.) To
avoid this problem, use the <tt/DateTimeDelta/ type.

<sect2>MySQL-3.23
<p>
MySQL-3.23 is now stable (3.23.51 as of this writing). MySQLdb
supports transactions if the <em/server/ supports them. Even then,
this does not guarantee that transactions will work. For that, you
must use a transaction-safe table (TST). Current TSTs are BDB and
InnoDB. Note that MySQL
generally operates in <tt/AUTOCOMMIT/ mode by default, and MySQLdb
assumes that <tt/AUTOCOMMIT/ is on by default. To change this, use the
<tt/SET AUTOCOMMIT=0/ SQL statement.

<sect2>MySQL-4.0
<p>
MySQL-4.0 is supported, though still alpha.


<sect1>DateTime
<p>If you have the <htmlurl
url="http://www.lemburg.com/files/python/mxDateTime.html"
name="mx.DateTime"> package installed (recommended), MySQLdb will use
it for date-related objects. Otherwise, these will be returned to
Python as strings. You can also modify the type conversion
dictionary to return these as other object classes, if you prefer.

<sect1>MySQLmodule<label id="MySQLmodule">
<p>
MySQLmodule, the older MySQL interface by Joe Skinner and others, is
also a split C/Python interface. <tt/MySQL/, the C portion, has an
interface similar to perl's DBI internally. In addition, there is
Python portion, <tt/Mysqldb/, which provides a DB API v1.0 interface,
written by James Henstridge.  MySQLdb-0.2.2 and up include
<tt/CompatMysqldb/, which is an adaptation of <tt/Mysqldb/ to
<tt/_mysql/. It should be considered experimental.

In contrast, MySQLdb's C portion, <tt><ref id="_mysql"></tt>, is
designed to mimic the MySQL C API in an object-oriented way; you
should not expect to move from <tt/MySQL/ to <tt/_mysql/ without a
fair amount of work. <tt><ref id="MySQLdb"></tt> provides a DB API
v2.0 interface, which has some changes from the v1.0 interface. Things
to watch out for in particular:

<table>
<tabular ca="foo">
Operation | Mysqldb | MySQLdb
@ Connecting | <tt>db = Mysqldb.Mysqldb("db@host user pass")</tt>
| <tt>db = MySQLdb.connect(db='db', host='host', user='user', passwd='pass')</tt>
@ Implicit cursor | <tt>db.execute(SQL)</tt> |
implicit cursors dropped from DB API v2.0; always use <tt>c = db.cursor()</tt>
@ Fetch row as dictionary | <tt>c.fetchDict()</tt>,
keys are "<em/table.column/" |
not standard; alternate cursor class <tt>DictCursor</tt>
provides a dictionary interface,
keys are "<em/column/" or "<em/table.column/" if there are two columns
with the same name; use SQL <tt/AS/ to rename fields.
@ Transactions | <tt>db.commit()</tt> and <tt>db.rollback()</tt>
both exist and silently do nothing <ref id="rollback" name="(danger!)">
| <tt>db.commit()</tt> and <tt>db.rollback()</tt> work if the MySQL
server can perform transactions; otherwise <tt>db.rollback()</tt>
always fails
<caption>Mysqldb to MySQLdb changes</tabular></table>

<sect1>Zope and ZMySQLDA

<p>I wrote a <htmlurl url="http://dustman.net/andy/python/ZMySQLDA"
name="ZMySQLDA"> for use with MySQLdb. It's adapted from ZOracleDA
from Digital Creations, makers of Zope.

<sect1>Documentation

<p>The web page documentation may be slightly ahead of the latest
release and may reflect features of the next release.  <sect1>FAQs
<p>A FAQ is available at <htmlurl
url="http://dustman.net/andy/python/MySQLdb/faq/MySQLdb-FAQ.html">.

<sect>_mysql module<label id="_mysql">
<P>
If you want to write applications which are portable across databases,
avoid using this module directly. <tt>_mysql</tt> provides an
interface which mostly implements the MySQL C API. For more
information, see the MySQL documentation. The documentation for this
module is intentionally weak because you probably should use the
higher-level <ref id="MySQLdb"> module. If you really need it, use the
standard MySQL docs and transliterate as necessary.

<sect1>MySQL C API translation
<p>
The MySQL C API has been wrapped in an object-oriented way. The only
MySQL data structures which are implemented are the <tt>MYSQL</tt>
(database connection handle) and <tt>MYSQL_RES</tt> (result handle)
types. In general, any function which takes <tt>MYSQL *mysql</tt> as
an argument is now a method of the connection object, and any function
which takes <tt>MYSQL_RES *result</tt> as an argument is a method of
the result object. Functions requiring none of the MySQL data
structures are implemented as functions in the module. Functions
requiring one of the other MySQL data structures are generally not
implemented.  Deprecated functions are not implemented. In all cases,
the <tt>mysql_</tt> prefix is dropped from the name. Most of the
<tt>conn</tt> methods listed are also available as MySQLdb Connection
object methods. Their use is non-portable.

<p>
Starting with MySQLdb-0.9.2, the connection and result objects are
subclassable types if you have at least Python-2.2.

<table>
<tabular ca="MySQL C API function mapping">
 C API | <tt>_mysql</tt>
@ <tt>mysql_affected_rows()</tt> | <tt>conn.affected_rows()</tt>
@ <tt>mysql_close()</tt> | <tt>conn.close()</tt>
@ <tt>mysql_connect()</tt> | <tt>_mysql.connect()</tt>
@ <tt>mysql_data_seek()</tt> | <tt>result.data_seek()</tt>
@ <tt>mysql_debug()</tt> | <tt>_mysql.debug()</tt>
@ <tt>mysql_dump_debug_info</tt> | <tt>conn.dump_debug_info()</tt>
@ <tt>mysql_escape_string()</tt> | <tt>_mysql.escape_string()</tt>
@ <tt>mysql_fetch_row()</tt> | <tt>result.fetch_row()</tt>
@ <tt>mysql_get_client_info()</tt> | <tt>_mysql.get_client_info()</tt>
@ <tt>mysql_get_host_info()</tt> | <tt>conn.get_host_info()</tt>
@ <tt>mysql_get_proto_info()</tt> | <tt>conn.get_proto_info()</tt>
@ <tt>mysql_get_server_info()</tt> | <tt>conn.get_server_info()</tt>
@ <tt>mysql_info()</tt> | <tt>conn.info()</tt>
@ <tt>mysql_insert_id()</tt> | <tt>conn.insert_id()</tt>
@ <tt>mysql_num_fields()</tt> | <tt>result.num_fields()</tt>
@ <tt>mysql_num_rows()</tt> | <tt>result.num_rows()</tt>
@ <tt>mysql_options()</tt> | <tt>_mysql.connect()</tt>
@ <tt>mysql_ping()</tt> | <tt>conn.ping()</tt>
@ <tt>mysql_query()</tt> | <tt>conn.query()</tt>
@ <tt>mysql_real_connect()</tt> | <tt>_mysql.connect()</tt>
@ <tt>mysql_real_query()</tt> | <tt>conn.query()</tt>
@ <tt>mysql_real_escape_string()</tt> | <tt>conn.escape_string()</tt>
@ <tt>mysql_row_seek()</tt> | <tt>result.row_seek()</tt>
@ <tt>mysql_row_tell()</tt> | <tt>result.row_tell()</tt>
@ <tt>mysql_select_db()</tt> | <tt>conn.select_db()</tt>
@ <tt>mysql_stat()</tt> | <tt>conn.stat()</tt>
@ <tt>mysql_store_result()</tt> | <tt>conn.store_result()</tt>
@ <tt>mysql_thread_id()</tt> | <tt>conn.thread_id()</tt>
@ <tt>mysql_thread_safe_client()</tt> | <tt>conn.thread_safe_client()</tt>
@ <tt>mysql_use_result()</tt> | <tt>conn.use_result()</tt>
@ <tt>CLIENT_*</tt> | <tt>MySQLdb.constants.CLIENT.*</tt>
@ <tt>CR_*</tt> | <tt>MySQLdb.constants.CR.*</tt>
@ <tt>ER_*</tt> | <tt>MySQLdb.constants.ER.*</tt>
@ <tt>FIELD_TYPE_*</tt> | <tt>MySQLdb.constants.FIELD_TYPE.*</tt>
@ <tt>FLAG_*</tt> | <tt>MySQLdb.constants.FLAG.*</tt>
<caption>MySQL C API function mapping
</tabular>
</table>

<sect1>Some _mysql examples

<P>Okay, so you want to use <tt/_mysql/ anyway. Here are some examples.

<p>The simplest possible database connection is:

<code>
import _mysql
db=_mysql.connect()
</code>

This creates a connection to the MySQL server running on the local
machine using the standard UNIX socket (or named pipe on Windows),
your login name (from the USER
environment variable), no password, and does not <tt/USE/ a database.
Maybe this will work for you, if you have set up a configuration file,
i.e. (<tt>~/.my.cnf</tt>). Chances are you need to supply more
information.

<code>
db=_mysql.connect("localhost","joebob","moonpie","thangs")
</code>

This creates a connection to the MySQL server running on the local
machine via a UNIX socket (or named pipe), the user name
"joebob", the password "moonpie", and selects the initial database
"thangs".

<P>We haven't even begun to touch upon all the parameters <tt/connect()/
can take.
For this reason, I prefer to use keyword parameters:

<code>
db=_mysql.connect(host="localhost",user="joebob",
                  passwd="moonpie",db="thangs")
</code>
This does exactly what the last example did, but is arguably easier
to read. But since the default host is "localhost", and if your
login name really was "joebob", you could shorten it to this:
<code>
db=_mysql.connect(passwd="moonpie",db="thangs")
</code>
UNIX sockets and named pipes don't work over a network, so if you specify a host other
than localhost, TCP will be used, and you can specify an odd port
if you need to (the default port is 3306):
<code>
db=_mysql.connect(host="outhouse",port=3307,passwd="moonpie",db="thangs")
</code>

<p>If you really had to, you could connect to the local host with TCP
by specifying the full host name, or 127.0.0.1.

<p>
There are some other parameters you can use, and most of them aren't
needed, except for one, which we'll get to momentarily. For the rest,
read the built-in documentation. Python 2.1's <tt/pydoc/ module is
great for this.

<P>So now you have an open connection as <tt/db/ and want to do a
query. Well, there are no cursors in MySQL, and no parameter
substitution, so you have to pass a complete query string to
<tt/db.query()/:
<code>
db.query("""SELECT spam, eggs, sausage FROM breakfast
            WHERE price < 5""")
</code>
There's no return value from this, but exceptions can be raised. The
exceptions are defined in a separate module, <tt/_mysql_exceptions/,
but <tt/_mysql/ exports them. Read the <htmlurl
url="http://www.python.org/peps/pep-0249.html"
name="DB API specification"> to find out what they are, or you can use
the catch-all <tt/MySQLError/.

<P>At this point your query has been executed and you need to get the
results. You have two options:
<code>
r=db.store_result()
# ...or...
r=db.use_result()
</code>
Both methods return a result object. What's the difference?
<tt/store_result()/ returns the entire result set to the client
immediately. If your result set is really large, this could be a
problem. One way around this is to add a <tt/LIMIT/ clause to your
query, to limit the number of rows returned. The other is to use
<tt/use_result()/, which keeps the result set in the server and sends
it row-by-row when you fetch. This does, however, tie up server
resources, and it ties up the connection: You cannot do any more
queries until you have fetched <em/all/ the rows. Generally I
recommend using <tt/store_result()/ unless your result set is really
huge and you can't use <tt/LIMIT/ for some reason.

<P>Now, for actually getting real results:
<CODE>
>>> r.fetch_row()
(('3','2','0'),)
</CODE>
This might look a little odd. The first thing you should know is,
<tt/fetch_row()/ takes some additional parameters. The first one is,
how many rows (<tt/maxrows/) should be returned. By default, it
returns one row. It may return fewer rows than you asked for, but
never more. If you set <tt/maxrows=0/, it returns all rows of the
result set. If you ever get an empty tuple back, you ran out of rows.


<p>The second parameter (<tt/how/) tells it how the row should be
represented. By default, it is zero which means, return as a tuple.
<tt/how=1/ means, return it as a dictionary, where the keys are the
column names, or <tt/table.column/ if there are two columns with the
same name (say, from a join). <tt/how=2/ means the same as <tt/how=1/
except that the keys are <em/always/ <tt/table.column/; this is for
compatibility with the old <tt/Mysqldb/ module.

<P>OK, so why did we get a 1-tuple with a tuple inside? Because we
implicitly asked for one row, since we didn't specify <tt/maxrows/.

<P>The other oddity is: Assuming these are numeric columns, why are
they returned as strings? Because MySQL returns all data as strings
and expects you to convert it yourself. This would be a real pain in
the ass, but in fact, <tt/_mysql/ can do this for you. (And
<tt/MySQLdb/ does do this for you.) To have automatic type conversion
done, you need to create a type converter dictionary, and pass this
to <tt/connect()/ as the <tt/conv/ keyword parameter.

<p>The keys of <tt/conv/ should be MySQL column types, which in the
C API are <tt/FIELD_TYPE_*/. You can get these values like this:

<code>
from MySQLdb.constants import FIELD_TYPE
</code>

By default, any column type that can't be found in <tt/conv/ is
returned as a string, which works for a lot of stuff. For our
purposes, we probably want this:

<code>
my_conv = { FIELD_TYPE.LONG: int }
</code>
This means, if it's a <tt/FIELD_TYPE_LONG/, call the builtin
<tt/int()/ function on it.  Note that <tt/FIELD_TYPE_LONG/ is an
<tt/INTEGER/ column, which corresponds to a C <tt/long/, which is also
the type used for a normal Python integer. But beware: If it's really
an <tt/UNSIGNED INTEGER/ column, this could cause overflows. For this
reason, <tt/MySQLdb/ actually uses <tt/long()/ to do the
conversion. But we'll ignore this potential problem for now.

<P>Then if you use <tt/db=_mysql.connect(conv=my_conv...)/, the
results will come back <tt/((3, 2, 0),)/, which is what you would
expect.

<sect>MySQLdb -- DB API interface<label id="MySQLdb">
<p>
MySQLdb is a thin Python wrapper around <tt><ref id="_mysql"></tt>
which makes it compatible with the Python DB API interface (version
2).  In reality, a fair amount of the code which implements the API is
in <tt>_mysql</tt> for the sake of efficiency.
<p>
The <htmlurl
url="http://www.python.org/topics/database/DatabaseAPI-2.0.html"
name="DB API specification"> should be your primary guide for using
this module. Only deviations from the spec and other
database-dependent things will be documented here.

<sect1>Functions and attributes 

<P>Only a few top-level functions and attributes are defined within
MySQLdb.

<descrip>
<tag><label id="connect()">connect(parameters...)</tag> Constructor
      for creating a connection to the database. Returns a Connection
      Object. Parameters are the same as for the MySQL C API.  In
      addition, there are a few additional keywords that correspond to
      what you would pass <tt/mysql_options()/ before connecting. Note
      that some parameters must be specified as keyword arguments! The
      default value for each parameter is NULL or zero, as
      appropriate. Consult the MySQL documentation for more
      details. The important parameters are:

<descrip>
      <tag>host</tag> 
            name of host to connect to. Default: use the local host 
            via a UNIX socket (where applicable)

      <tag>user</tag> 
            user to authenticate as. Default: current effective user.

      <tag>passwd</tag> 
            password to authenticate with. Default: no password.

      <tag>db</tag> 
            database to use. Default: no default database.

      <tag>port</tag>
	    TCP port of MySQL server. Default: standard port (3306).

      <tag>unix_socket</tag>
	    location of UNIX socket. Default: use default location or
            TCP for remote hosts.

      <tag>conv</tag> type conversion dictionary.
            Default: a copy of <tt/MySQLdb.converters.conversions/

      <tag>compress</tag> Enable protocol compression. Default: no compression.

      <tag>connect_timeout</tag> Abort if connect is not completed within
            given number of seconds. Default: no timeout (?)

      <tag>named_pipe</tag> Use a named pipe (Windows). Default: don't.

      <tag>init_command</tag> Initial command to issue to server upon
            connection. Default: Nothing.

      <tag>read_default_file</tag> MySQL configuration file to read; see
            the MySQL documentation for <tt/mysql_options()/.

      <tag>read_default_group</tag> Default group to read; see the MySQL
            documentation for <tt/mysql_options()/.

      <tag>cursorclass</tag> cursor class that <tt/cursor()/ uses,
            unless overridden. Default: <tt/MySQLdb.cursors.Cursor/.
	    <em/This must be a keyword parameter./

      <tag>unicode</tag> If set, CHAR and VARCHAR columns are returned
            as Unicode strings, using the specified character set.
            None means to use a default encoding.

</descrip>

<tag>apilevel</tag> 
      String constant stating the supported DB API level. '2.0'

<tag>threadsafety</tag> Integer constant stating the level of thread
      safety the interface supports. As of MySQLdb version 0.9.0, this
      is set to 1, which means: Threads may share the module.
      <p>The MySQL protocol can not handle multiple threads using the
      same connection at once. Some earlier versions of MySQLdb utilized locking
      to achieve a threadsafety of 2. While this is not terribly hard
      to accomplish using the standard Cursor class (which uses
      <tt/mysql_store_result()/), it is complicated by SSCursor (which
      uses <tt/mysql_use_result()/; with the latter you must ensure
      all the rows have been read before another query can be executed.
      It is further complicated by the addition of transactions, since
      transactions start when a cursor execute a query, but end when
      <tt/COMMIT/ or <tt/ROLLBACK/ is executed by the Connection object.
      Two threads cannot share a connection while a transaction is in
      progress, in addition to not being able to share it during query
      execution. This excessively complicated the code to the point where
      it just isn't worth it. <p>The general upshot of this is: Don't
      share connections between threads. It's really not worth your effort
or mine, and in the end, will probably hurt performance, since the MySQL
      server runs a separate thread for each connection.
      You can certainly do things like
      cache connections in a pool, and give those connections to one
      thread at a time. If you let two threads use a connection simultaneously,
      the MySQL client library will probably upchuck and die.
      You have been warned.

      <p>For threaded applications, try using a connection pool.
      This can be done using the 
      <htmlurl url="http://dustman.net/andy/python/Pool" name="Pool module">.

<tag>paramstyle</tag> String constant stating the type of parameter
      marker formatting expected by the interface. Set to 'format' =
      ANSI C printf format codes, e.g. '...WHERE name=%s'. If a
      mapping object is used for conn.execute(), then the interface
      actually uses 'pyformat' = Python extended format codes,
      e.g. '...WHERE name=%(name)s'. However, the API does not
      presently allow the specification of more than one style in
      paramstyle.

      Compatibility note: The older MySQLmodule uses a similar
      parameter scheme, but requires that quotes be placed around
      format strings which will contain strings, dates, and similar
      character data. This is not necessary for MySQLdb. It is
      recommended that %s (and not '%s') be used for all parameters,
      regardless of type. The interface performs all necessary
      quoting.

      Note that any literal percent signs in the query string passed
      to execute() must be escaped, i.e. %%.

<tag><label id="conversions">conv</tag> A dictionary mapping MySQL types
      (from <TT>FIELD_TYPE.*</TT>) to callable Python objects (usually
      functions) which convert from a string to the desired type; and
      mapping Python types to callable Python objects which convert
      values of this type to a SQL literal string value. This is
      initialized with reasonable defaults for most types. When
      creating a Connection object, you can pass your own type
      converter dictionary as a keyword parameter. Otherwise, it uses
      a copy of <tt>MySQLdb.converters.conversions</tt>. The dictionary
      includes some of the factory functions from the
      <tt>DateTime</tt> module, if it is available. Several
      non-standard types are returned as strings,
      which is how MySQL returns all columns. For more details, see
      the built-in module documentation.

<P>As of MySQL-3.23, MySQL supports different character sets in the
server, and a new quoting function, <tt/mysql_real_escape_string()/.
This requires the string quoting function to be a method bound to
the connection object. MySQLdb handles this for you automatically.
However, if you feel the need to do something goofy with your strings,
you will have to modify the dictionary after opening the connection.
In practice, you should never have to worry about this. This also
applies to Unicode strings, if enabled.

</descrip>

<sect1>Connection Objects
<P>Connection objects are returned by the <tt>connect()</tt> function.
<descrip>

<tag>commit()</tag> If the database and the tables support
      transactions, this commits the current transaction; otherwise
      this method successfully does nothing.

<tag><label id="rollback">rollback()</tag> If the database and tables
      support transactions, this rolls back (cancels) the current
      transaction; otherwise a <tt>NotSupportedError</tt> is raised.

Compatibility note: The older <ref id="MySQLmodule"> defines this method,
      which sucessfully does nothing. This is dangerous behavior, as a
      successful rollback indicates that the current transaction was
      backed out, which is not true, and fails to notify the
      programmer that the database now needs to be cleaned up by other
      means.

<tag>cursor([cursorclass])</tag> MySQL does not support cursors;
      however, cursors are easily emulated.  You can supply an
      alternative cursor class as an optional parameter.  If this is
      not present, it defaults to the value given when creating the
      connection object, or the standard <tt/Cursor/ class. Also see
      the additional supplied cursor classes in the <ref id="usage">
      section.

<tag>begin()</tag> Explicitly start a transaction. Normally you do
      not need to use this: Executing a query implicitly starts a new
      transaction if one is not in progress. If AUTOCOMMIT is on, you
      can use <tt/begin()/ to temporarily turn it off. AUTOCOMMIT will
      resume after the next <tt/commit()/ or <tt/rollback/.

</descrip>

<p>There are many more methods defined on the connection object which
are MySQL-specific. For more information on them, consult the internal
documentation using <tt/pydoc/.

<sect1>Cursor Objects
<p>
<descrip>
<tag>callproc()</tag>
      Not implemented.

<tag>close()</tag>
      Closes the cursor. Future operations raise <tt/ProgrammingError/.
      If you are using <ref id="SSCursor" name="server-side cursors">,
      it is very important to close the cursor when you are done with
      it and before creating a new one.

<tag/insert_id()/
      Returns the last <tt/AUTO_INCREMENT/ field value inserted
      into the database. (Non-standard)

<tag/info()/ Returns some information about the last query. Normally
      you don't need to check this. With the default cursor, any MySQL
      warnings cause <tt/Warning/ to be raised. If you are using a
      cursor class without warnings, then you might want to use
      this. See the MySQL docs for <tt/mysql_info()/. (Non-standard)

<tag>setinputsizes()</tag>
      Does nothing, successfully.

<tag>setoutputsizes()</tag>
      Does nothing, successfully.

<tag>nextset()</tag>
      Advances the cursor to the next result set, discarding the remaining
      rows in the current result set. If there are no additional result
      sets, it returns None; otherwise it returns a true value.

      Note that MySQL presently doesn't support multiple result sets.

</descrip>
<sect1>Some examples

<p>The <tt/connect()/ method works nearly the same as with <tt/_mysql/:
<code>
import MySQLdb
db=MySQLdb.connect(passwd="moonpie",db="thangs")
</code>
To perform a query, you first need a cursor, and then you can execute
queries on it.
<code>
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
            WHERE price < %s""", (max_price,))
</code>
In this example, <tt/max_price=5/ Why, then, use <tt/%s/ in the
string? Because MySQLdb will convert it to a SQL literal value, which
is the string '5'. When it's finished, the query will actually say,
"...WHERE price < 5".

<p>Why the tuple? Because the DB API requires you to pass in any
parameters as a sequence.

<p>And now, the results:
<CODE>
>>> c.fetchone()
(3L, 2L, 0L)
</CODE>
Quite unlike the <tt/_mysql/ example, this returns a single tuple,
which is the row, and the values are properly converted by default...
except... What's with the L's?

<P>As mentioned earlier, while MySQL's INTEGER column translates
perfectly into a Python integer, UNSIGNED INTEGER could overflow, so
these values are converted to Python long integers instead. Prior to
Python 1.6, long integers retained the L when converted to strings
with <tt/str()/. In 1.6 and later, <tt/str()/ does not include the L.
Of course, the L always prints when using <tt/repr()/, which is what
has happened here.

<P>When you are finished with a transaction, you should execute either
<tt/db.commit()/ or <tt/db.rollback()/. If your server and tables
don't support transactions, <tt/commit()/ will still work, but
<tt/rollback()/ will raise an exception. Note carefully that these are
methods of the <em/connection/ and not methods of the <em/cursor/,
even though <tt/c.execute(...)/ is what started the transaction.

<P>If you wanted more rows, you could use <tt/c.fetchmany(n)/ or
<tt/c.fetchall()/. These do exactly what you think they do. On
<tt/c.fetchmany(n)/, the <tt/n/ is optional and defaults to
<tt/c.arraysize/, which is normally 100. Both of these methods return
a sequence of rows, or an empty sequence if there are no more rows.
If you use a weird cursor class, the rows themselves might not be
tuples.

<P>Note that in contrast to the above, <tt/c.fetchone()/ returns <tt/None/
when there are no more rows to fetch.

<P>The only other method you are very likely to use is when you have to
do a multi-row insert:
<CODE>
c.executemany(
    """INSERT INTO breakfast (name, spam, eggs, sausage, price)
    VALUES (%s, %s, %s, %s, %s)""",
    [
      ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
      ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
      ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
    ] )
</CODE>
Here we are inserting three rows of five values. Notice that there is
a mix of types (strings, ints, floats) though we still only use
<tt/%s/. And also note that we only included format strings for one
row. MySQLdb picks those out and duplicates them for each row.
<footnote>Baked beans are off!</footnote>

<sect>Using and extending<label id="usage">

<P>In general, it is probably wise to not directly interact with the
DB API except for small applicatons. Databases, even SQL databases,
vary widely in capabilities and may have non-standard features. The DB
API does a good job of providing a reasonably portable interface but
some methods are non-portable. Specifically, the parameters accepted
by <tt><ref id="connect()"></tt> are completely implementation-dependent.

If you believe your application may need to run on several different
databases, the author recommends the following approach, based on
personal experience: Write a simplified API for your application which
implements the specific queries and operations your application needs
to perform. Implement this API as a base class which should be have
few database dependencies, and then derive a subclass from this which
implements the necessary dependencies. In this way, porting your
application to a new database should be a relatively simple matter of
creating a new subclass, assuming the new database is reasonably
standard.

For an example of this, see the author's
<htmlurl url="http://dustman.net/andy/python"
name="SQLDict module">, which allows standard queries to be
defined and accessed using an object which looks like a
dictionary, and reads/writes user-defined objects.

Because MySQLdb's Connection and Cursor objects are written in Python,
you can easily derive your own subclasses. There are several Cursor
classes in MySQLdb.cursors:
<p>
<descrip>
<tag>BaseCursor</tag> The base class for Cursor objects.
This does not raise Warnings.

<tag>CursorWarningMixIn</tag> Causes the Warning exception to be raised
on queries which produce warnings.

<tag>CursorStoreResultMixIn</tag> Causes the Cursor to use the
<tt>mysql_store_result()</tt> function to get the query result. The
entire result set is stored on the client side.

<tag><label id="SSCursor">CursorUseResultMixIn</tag> Causes the cursor to use the
<tt>mysql_use_result()</tt> function to get the query result. The
result set is stored on the server side and is transferred row by row
using fetch operations. 

<tag>CursorTupleRowsMixIn</tag> Causes the cursor to return rows
as a tuple of the column values.

<tag>CursorDictRowsMixIn</tag> Causes the cursor to return rows
as a dictionary, where the keys are column names and the values
are column values. Note that if the column names are not unique,
i.e., you are selecting from two tables that share column names,
some of them will be rewritten as <em/table.column/.
This can be avoided by using
the SQL <tt>AS</TT> keyword. (This is yet-another reason not to use
<tt/*/ in SQL queries, particularly where <tt/JOIN/ is involved.

<tag>Cursor</tag> The default cursor class. This class is composed
of <tt>CursorWarningMixIn, CursorStoreResultMixIn, CursorTupleRowsMixIn,</tt>
and <tt>BaseCursor</tt>, i.e. it raises <tt>Warning</tt>, uses
<tt>mysql_store_result()</tt>, and returns rows as tuples.

<tag>DictCursor</tag> Like <tt/Cursor/ except it returns rows as
dictionaries.

<tag>SSCursor</tag> A "server-side" cursor. Like <tt/Cursor/ but uses
<tt/CursorUseResultMixIn/. 
Use only if you are dealing with potentially large result sets.

<tag/SSDictCursor/ Like <tt/SSCursor/ except it returns rows as
dictionaries.

<tag/XXXCursorNW/ Cursors with the "NW" suffix do not raise Warnings.

</descrip>
<p>For an example of how to use these classes,
read the code. If you need something more exotic than this,
you will have to roll your own.
</article>



