diff --git a/MySQLdb/MANIFEST.in b/MySQLdb/MANIFEST.in index 91d8590..a3ff883 100644 --- a/MySQLdb/MANIFEST.in +++ b/MySQLdb/MANIFEST.in @@ -1,7 +1,5 @@ prune CVS -recursive-include doc *.html *.sgml -recursive-include examples * -include README.MySQLmodule +recursive-include doc *.txt *.html include license.py include MANIFEST.in include MANIFEST diff --git a/MySQLdb/doc/MySQLdb-FAQ.sgml b/MySQLdb/doc/MySQLdb-FAQ.sgml deleted file mode 100644 index bfd0225..0000000 --- a/MySQLdb/doc/MySQLdb-FAQ.sgml +++ /dev/null @@ -1,135 +0,0 @@ - -
-MySQLdb FAQ -<author>Andy Dustman -<date>$Id$ -<sect>Compiling <tt/_mysql.so/ -<P>Here are some common errors that happen during the build. -This section covers UNIX/Linux problems only, as I don't do Windows. -<tt/.so/ is a dynamically loading library on Linux and most other UNIX -variants; a few use extensions other than <tt/.so/. Windows probably -uses <tt/.dll/. -<sect1>ImportError: libmysqlclient.so.6: cannot open shared object file: -No such file or directory -<P> -You have dynamic MySQL libraries, and by default, your compiler links -<tt/_mysql.so/ against these, but these are not on your loader path -when you start Python. -You have two basic options: -<p> -<enum> -<item> -Modify setup.py so that it links against the static library; see the comments. -<item> -If your linker supports a run-time loader path switch, you can set this -in setup.py as well. -<item> -Change your system environment so that the MySQL libraries are on -your loader path. With Linux, you can modify <tt>/etc/ld.so.conf</tt> (see -<tt/man ldconfig/ for more details) or you can add to or create the -<tt/LD_LIBRARY_PATH/ environment variable before starting Python, i.e. -<p><code> -LD_LIBRARY_PATH=/path/to/mysql/libs python ... # Bourne-ish shell -</code> -</enum> -<sect1>ImportError: ./_mysql.so: undefined symbol: PyLong_FromUnsignedLongLong -<p> -<tt/PyLong_FromUnsignedLongLong()/ first appears in Python 1.5.2, so you are -linking against an earlier version. You may also have more than one version -installed. Get Python 1.5.2 or newer from your vendor or python.org. - -<sect1>ImportError: ./_mysql.so: undefined symbol: uncompress -<P> -It seems that MySQL-3.23 client libraries require libz for gzip -compression. setup.py should add this automatically. - -<sect1>./_mysql.c:33: mysql.h: No such file or directory -<P>The include path (-I) to your MySQL include files is wrong; modify -setup.py. OR: You don't have the MySQL development stuff loaded. If you -are using the Red Hat RPMs, you need the <tt/MySQL-devel/ RPM to compile -<tt/_mysql.so/. However, if you link against the static MySQL -libraries (see above), you can install <tt/_mysql.so/ on a system -that does not have the MySQL client libraries (<tt/libmysqlclient/). - -<sect1>I'm using Windows... -<P>Say no more. -<P>I don't use Windows. setup.py is supposed to work for building. -There may also be a link to some user-contributed binaries on the web site. -</sect1> -<sect> -Trouble with ZMySQLDA -<sect1>I installed MySQLdb but ZMySQLDA can't find it. -<p>Probably you installed a binary version of Zope which comes with -its own Python interpreter. You will have to compile MySQLdb against -that particular Python installation. Find out where it's python binary -lives and use that to run setup.py. -</sect1> -<sect1>I'm getting these stupid L's on my INTEGER columns. -<p>Yup, they have to be converted to long integers to avoid overflows -on UNSIGNED INT columns. Solutions: Use a <tt/fmt=%d/ attribute on your -<tt/dtml-var/ elements; Wait for Zope 2.4 which comes with Python 2.1 -which doesn't add the L. -</sect1> -<sect1>I get SQL syntax errors on a LIMIT clause, and I didn't put in -a LIMIT clause! - -<p>Z SQL Methods have a <tt/max_rows/ parameter. If this is set to a -non-zero value, ZMySQLDA adds a LIMIT clause to SELECT statements to -enforce this. This is a big performance gain, particularly if the -result set could be big. If it is interfering with something, set -<tt/max_rows/ to zero, and it won't add a LIMIT clause. In particular, -you will probably have to do this when inserting rows with -AUTO_INCREMENT columns, because typically you use SELECT thereafter to -get LAST_INSERT_ID(), and LIMIT can mess this up. - -<sect>Using MySQLdb -<p> -MySQLdb is a -<htmlurl url="http://www.python.org/topics/database/DatabaseAPI-2.0.html" -name="Python Database API Specification 2.0"> database module, so you -should be familiar with the spec. Deviations from the spec are documented in the -<htmlurl url="http://dustman.net/andy/python/MySQLdb/doc/MySQLdb.html" -name="MySQLdb documentation">. - -<sect1>cursor.rollback() always fails! - -<p>MySQLdb now supports transactions if the server supports -transaction-safe tables (TSTs) and you are using them. If your server -doesn't support them, rollbacks will always fail, as they should, -because it can't do what you asked. Even if your server does support -them, rollbacks will fail if you modified any non-TST tables. - -<p>OTOH, <tt/cursor.commit()/, which attempts to commit the -transaction to the database, <em/always/ succeeds, because MySQL -essentially is always in auto-commit mode (unless you told it -otherwise). - -<sect1>How do I use some of the special MySQL features? - -<P>First answer: Don't, if you can avoid it. Your program will not be -portable to other databases. - -<P>Second answer: Nearly all the special API calls are implemented on -the _mysql connection object, and the MySQLdb connection object can -also invoke them. See the built-in module docs to find out what ones -are implemented, and the MySQL C API docs to see what they do. - -<sect1>I still wanna use _mysql directly. - -<p>Well, it <tt/may/ be appropriate in some cirumstances. ZMySQLDA -does this, because Zope's ZRDB module is an API in itself, and too -many layers of APIs tend to make a mess of things. Besides, it was -actually pretty easy to do it that way and it probably improves the -performance a bit. -<enum> -<item> -Read the MySQL docs, particularly the C API, for an overview. -<item> -Read the MySQLdb docs. This shows how the C API is transliterated -into Python. Plus some examples are in there. -<item> -Read the MySQLdb sources, particularly MySQLdb/cursors.py. That one -file contains most of the gory details, particularly in the -execute and _query methods. -</enum> -</article> diff --git a/MySQLdb/doc/MySQLdb.sgml b/MySQLdb/doc/MySQLdb.sgml deleted file mode 100644 index 7cd2bd1..0000000 --- a/MySQLdb/doc/MySQLdb.sgml +++ /dev/null @@ -1,749 +0,0 @@ -<!DOCTYPE linuxdoc system> -<article> -<title>MySQLdb: a Python interface for MySQL -<author>Andy Dustman -<date>$Id$ - -<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> - - -