Version 1.1.7

This commit is contained in:
adustman
2004-10-31 02:11:20 +00:00
parent 2a2c1d3791
commit 2d32380e68
6 changed files with 633 additions and 1015 deletions

View File

@ -1,691 +0,0 @@
2004-09-19 adustman <adustman@tweek.neosouth.net>
* _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py:
* Removed some old-style Python stuff from setup.py
* Added a bit of documentation on ssl parameter to Connection
* Version 1.1.5
* MANIFEST.in: Include new ChangeLog
* setup.py: Restore missing common on include_dirs
2004-09-11 adustman <adustman@tweek.neosouth.net>
* ChangeLog: *** empty log message ***
* _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py:
Version 1.1.4
* setup.py: changed include and library path order
* MySQLdb/connections.py: fix super class reference in autocommit()
* Tested against MySQL-4.1.4a with InnoDB tables
* _mysql.c: Re-fix typo
* _mysql.c:
Fix _mysql_Execption() typo. Code is only compiled when MySQL-4.1
is in use, and I haven't done any actual testing against 4.1 yet.
Please report any bugs to the SourceForge tracker.
2004-09-11 adustman <adustman@tweek.neosouth.net>
* _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py:
Version 1.1.4
* setup.py: changed include and library path order
* MySQLdb/connections.py: fix super class reference in autocommit()
* Tested against MySQL-4.1.4a with InnoDB tables
* _mysql.c: Re-fix typo
* _mysql.c:
Fix _mysql_Execption() typo. Code is only compiled when MySQL-4.1
is in use, and I haven't done any actual testing against 4.1 yet.
Please report any bugs to the SourceForge tracker.
2004-09-08 adustman <adustman@tweek.neosouth.net>
* _mysql.c, setup.py, MySQLdb/__init__.py: Version 1.1.3
* _mysql.c: restored missing mysql_errno() call (bug #1023466)
* _mysql.c: Only try to use SSL support if HAVE_OPENSSL is defined.
Raise NotSupportedError if ssl is requested but not available.
2004-09-06 adustman <adustman@tweek.neosouth.net>
* ChangeLog, _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/times.py:
General cleanups.
* Turn autocommit off initially
* Add support for mysql_autocommit, _commit, and _rollback API functions
(new in MySQL-4.1)
* Remove Connection.begin(); use SQL BEGIN or START TRANSACTION instead
* pytimes (standard datetime module) is now the default implementation
* Detect and handle MySQL-4.1 and newer TIMESTAMP (looks like DATETIME)
* UnicodeType and ObjectType now always handled (required features)
* Ditch support for L at the end of long integer
* Remove z and crypt libs if building for Windows
* Version 1.1.2
* setup.py: Don't include z and crypt libs on Windows.
* _mysql.c: Conditionally define uint on all platforms.
* MySQLdb/cursors.py: Fix indentation error (again)
* _mysql.c: Fix bug #992756:
* Embedded server: List of groups was not NULL-terminated correctly.
* MySQLdb/cursors.py: Fix bug #989262:
* Changed errant tab to spaces in cursors.py
* _mysql.c, setup.py, MySQLdb/__init__.py: Fixes for bug #999588:
* Use os.environ.get() instead of os.getenv() in setup.py
* Use PySequence_Length() instead of PySequence_Check() in _mysql.c
Bump version to 1.0.1b1
2004-09-06 adustman <adustman@tweek.neosouth.net>
* ChangeLog, _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/times.py:
General cleanups.
* Turn autocommit off initially
* Add support for mysql_autocommit, _commit, and _rollback API functions
(new in MySQL-4.1)
* Remove Connection.begin(); use SQL BEGIN or START TRANSACTION instead
* pytimes (standard datetime module) is now the default implementation
* Detect and handle MySQL-4.1 and newer TIMESTAMP (looks like DATETIME)
* UnicodeType and ObjectType now always handled (required features)
* Ditch support for L at the end of long integer
* Remove z and crypt libs if building for Windows
* Version 1.1.2
* setup.py: Don't include z and crypt libs on Windows.
* _mysql.c: Conditionally define uint on all platforms.
* MySQLdb/cursors.py: Fix indentation error (again)
* _mysql.c: Fix bug #992756:
* Embedded server: List of groups was not NULL-terminated correctly.
* MySQLdb/cursors.py: Fix bug #989262:
* Changed errant tab to spaces in cursors.py
* _mysql.c, setup.py, MySQLdb/__init__.py: Fixes for bug #999588:
* Use os.environ.get() instead of os.getenv() in setup.py
* Use PySequence_Length() instead of PySequence_Check() in _mysql.c
Bump version to 1.0.1b1
2004-06-07 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, README, _mysql.c, setup.py:
Bump version. Update README. Convert all classes to new-style.
2004-06-06 adustman <adustman@tweek.neosouth.net>
* README, _mysql.c, setup.py, MySQLdb/__init__.py: 1.0.0 (D-Day)
2004-05-19 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/mxdatetimes.py, MySQLdb/pytimes.py, MySQLdb/sets.py, MySQLdb/times.py, _mysql.c, _mysql_exceptions.py, setup.cfg, setup.py:
Initial conversion to modern Python.
* _mysql.c, setup.py, MySQLdb/__init__.py: Version bump (1.0.0c2)
2004-05-18 adustman <adustman@tweek.neosouth.net>
* MySQLdb/pytimes.py: Fix bug #933911
* _mysql.c: Fix bug #955031
* setup.cfg: Fix bug #955032
2004-05-16 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, _mysql.c, setup.py: Version Bump
2004-02-29 adustman <adustman@tweek.neosouth.net>
* setup.py: Fix bug #897344
* MySQLdb/__init__.py: Fix bug #902024
2003-12-30 adustman <adustman@tweek.neosouth.net>
* _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py:
* Check for module initialization failure (extremely rare)
* The MySQL FIELD_TYPE converter can now be a sequence of 2-tuples.
Item 0 is a bit mask (using FLAG.*) which must be matched. This should
be an integer. Item 1 is the conversion function. If item 0 is not an
integer, then this function is considered the default converter for
this FIELD_TYPE. Note that these tuples are considered when the query
has been executed and the result is available, so it doesn't add a
per-row overhead.
* As a result of the above, BINARY BLOB fields are now returned as
character arrays using the array.array class. Non-BINARY BLOB fields
(i.e. TEXT) are returned as strings. If unicode is enabled, they are
returned as unicode strings.
* Bump version to 0.9.3b3.
2003-12-13 adustman <adustman@tweek.neosouth.net>
* MySQLdb/converters.py:
https://sourceforge.net/tracker/?func=detail&aid=850174&group_id=22307&atid=374932
Use more precision for floats; str(<float>) doesn't return full precision.
2003-11-27 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Preliminary SSL support. Adds a ssl parameter to connect().
ssl should be a mapping. These are the recognized keys:
ca*, cert*, capath, key*, cipher
Items marked with * are required. All values must be strings.
They are described here:
http://www.mysql.com/doc/en/SSL_options.html
You're probably better off putting these variables into an
option file and using read_option_file instead.
SSL is supported in MySQL-4.0 and newer. Even if you don't
specify all the required parameters, the connection will probably
succeed, although without SSL.
This is not yet tested in any significant way.
2003-11-23 adustman <adustman@tweek.neosouth.net>
* _mysql.c, setup.py, MySQLdb/__init__.py: Version bump
* MySQLdb/converters.py, MySQLdb/mxdatetimes.py, MySQLdb/pytimes.py, MySQLdb/stringtimes.py, MySQLdb/times.py:
Time-handling updates. New load order is:
mxdatetime (wrapper around mx.DateTime)
pytimes (wrapper around Python-2.3+ datetime)
stringtimes (minimal string implementation)
The logic is, if you're running Python-2.3 and are have mx.Datetime,
you probably want to use that instead of datetime.
2003-11-22 adustman <adustman@tweek.neosouth.net>
* MySQLdb/pytimes.py: Bug #816721
* _mysql.c: Bug #811636 fix (?)
2003-09-07 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py: info() might return None or empty string
* MySQLdb/connections.py:
Don't treat FIELD_TYPE.CHAR as a character type, it's really
a TINYINT (FIELD_TYPE.TINY).
* MySQLdb/connections.py, _mysql.c: Bug#778822
* setup.py: Fix version number correctly
* setup.py, MySQLdb/__init__.py, _mysql.c: Version bump
2003-07-11 adustman <adustman@tweek.neosouth.net>
* setup.py: Include new time handling modules
* MySQLdb/mxdatetimes.py, MySQLdb/stringtimes.py:
Split out old Date/Time handling classes into separate modules
* MySQLdb/pytimes.py: Finish up TimeDelta_or_None
2003-07-10 adustman <adustman@tweek.neosouth.net>
* CHANGELOG, MySQLdb/times.py:
Add support for Python 2.3 datetime classes.
2003-07-08 adustman <adustman@tweek.neosouth.net>
* CHANGELOG, MySQLdb/__init__.py, setup.py: Bump version numbers.
* _mysql.c: Bump version and remove some unneccesary casts that seem to
break things when using Python 2.3.
2003-07-07 adustman <adustman@tweek.neosouth.net>
* MySQLdb/converters.py: Fix bug 605849 (I hope).
* _mysql.c: Fix member access problems
2003-04-21 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Eliminate use of deprecated PyArg_NoArgs()
* _mysql.c: Dumb typo
2003-04-19 adustman <adustman@tweek.neosouth.net>
* README, setup.py: Build and documentation updates
2002-08-22 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, CHANGELOG, _mysql.c, setup.py:
Embedded server support
* _mysql.c: Clean up compiler warnings about
assignment discards qualifiers from pointer target type
2002-08-02 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Windows (blech) compatibility changes. (Gerhard H<>ring)
2002-08-01 adustman <adustman@tweek.neosouth.net>
* CHANGELOG: CHANGELOG
* _mysql.c: Not supporting GC for python < 2.2
* MANIFEST.in, pymemcompat.h: Memory API updates
* MySQLdb/connections.py: Ignore exception from close() in __del__
* _mysql.c: GC for Python 2.2+
2002-07-21 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, CHANGELOG, _mysql.c, setup.py: 0.9.2 (finally)
2002-07-16 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py:
Revert execute behavior: Do not use % operator when there are no args
2002-07-10 adustman <adustman@tweek.neosouth.net>
* README: Rewrite
* setup.cfg: Packaging cleanups
* MySQLdb/__init__.py, MySQLdb/cursors.py, CHANGELOG, _mysql.c, setup.py:
Version 0.9.2c3, see CHANGELOG
2002-07-03 adustman <adustman@tweek.neosouth.net>
* MySQLdb/converters.py:
Revert returning BLOBs as arrays, since MySQL doesn't distinquish
between TEXT and BLOB types. (Skip Montanaro)
* MySQLdb/connections.py:
Passing both conv and unicode to connect was broken (Skip Montanaro)
2002-07-02 adustman <adustman@tweek.neosouth.net>
* setup.py: FreeBSD/OpenBSD update
2002-07-01 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py: Fix dumb (but working) iterator implementation
* doc/MySQLdb.sgml: Doc updates
2002-06-26 adustman <adustman@tweek.neosouth.net>
* _mysql.c:
Add _mysql.thread_safe() (boolean, true if linked with thread-safe lib)
2002-06-24 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, _mysql.c, setup.py: Smack my version up
2002-06-23 adustman <adustman@tweek.neosouth.net>
* MySQLdb/connections.py, MySQLdb/cursors.py, CHANGELOG:
Some errorhandler cleanups
2002-06-20 adustman <adustman@tweek.neosouth.net>
* CHANGELOG: *** empty log message ***
* MySQLdb/connections.py: Make the new unicode option actually work
* MySQLdb/cursors.py: Add nextset() dummy stub
* MySQLdb/converters.py: BLOBs as array support
* MySQLdb/connections.py:
More Python 2.2 and doc updates. Return blobs as array.
The unicode option to connect() causes (VAR)CHAR columns
to be returned as unicode stings.
* _mysql.c: Lots of Python 2.2 updates, especially documentation
2002-06-18 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, _mysql.c, MANIFEST.in:
Mostly documentation updates, and some code cleanups
2002-06-15 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py:
Make executemany iterate over queries that don't use multiple VALUES
2002-04-28 adustman <adustman@tweek.neosouth.net>
* CHANGELOG, _mysql.c, setup.py:
packaging changes, pre-emptive version bump
* setup.py: Bump version
* MySQLdb/cursors.py:
Errorhandler was broken in cursor
CVSr ----------------------------------------------------------------------
* CHANGELOG: changelog
* MySQLdb/__init__.py: Version bump
* _mysql.c: Macro cleanups
2002-04-27 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Fix memory leak in _mysql_escape_dict. (Danny Yoo)
SSCursor.fetchall() (_mysql_ResultObject_fetch_row) didn't properly
increase the size of the result tuple if the result set was more than
1000 rows. (Danny Yoo)
2002-03-19 adustman <adustman@tweek.neosouth.net>
* _mysql.c: More (de)allocation cleanups, based on suggestions from
python-dev and Skip Montanaro
* _mysql.c: Use modern allocation with modern Python
2002-03-14 adustman <adustman@tweek.neosouth.net>
* MySQLdb/connections.py: Elminate debugging statement.
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, _mysql.c, setup.py:
Bump version. Minor Alpha Linux update. Clear errorhandler on close.
2002-03-01 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Fix a memory leak if the connect fails
2002-01-29 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py: Stricter regex for finding INSERT values
([ #505295 ] Wrong regexp in executemany() function.)
2002-01-25 adustman <adustman@tweek.neosouth.net>
* CHANGELOG: changes
* MySQLdb/__init__.py: Verision bump.
* _mysql.c:
Use modern memory deallocation on modern versions of Python.
* setup.py:
Rework platform config a bit, default to thread-safe client.
2001-12-29 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py: Fix fetchmany().
2001-12-24 adustman <adustman@tweek.neosouth.net>
* setup.py: Fix version.
* MySQLdb/connections.py, MySQLdb/cursors.py, doc/.cvsignore, .cvsignore, CHANGELOG, setup.py:
Version 0.9.2a1. Unicode + DB-API extensions.
2001-12-23 adustman <adustman@tweek.neosouth.net>
* _mysql.c, MySQLdb/__init__.py: 0.9.2 alpha 1
* MySQLdb/converters.py: Unicode support.
2001-12-22 adustman <adustman@tweek.neosouth.net>
* _mysql.c: str() can fail in some cases, particularly unicode.
Watch for it to prevent core dumps.
2001-12-03 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py:
Fix cursor.rownumber for CursorStoreResultMixIn.fetchmany()
and implement cursor.rownumber for CursorUseResultMixIn.fetchXXX().
2001-11-28 adustman <adustman@tweek.neosouth.net>
* setup.py: Catch more *bsd platforms. (Suggested by Ragnar Beer)
2001-11-07 adustman <adustman@tweek.neosouth.net>
* setup.py: Simplify the various configurations.
Solaris might be fixed for gcc and broken for standard compiler.
2001-10-31 adustman <adustman@tweek.neosouth.net>
* README: Some additional Zope notes.
* CHANGELOG: Mac OS X updates
* setup.py: Link with -flat_namespace on Mac OS X/darwin. (Dan Grassi)
2001-10-25 adustman <adustman@tweek.neosouth.net>
* MySQLdb/cursors.py:
Do some renaming suggested by recent DB-SIG discussions.
This should not break anything unless you are using private members.
2001-10-23 adustman <adustman@tweek.neosouth.net>
* CHANGELOG, setup.py: netbsd config
2001-10-17 adustman <adustman@tweek.neosouth.net>
* CHANGELOG, MySQLdb/__init__.py, README, _mysql.c, setup.py:
0.9.0 updates
2001-10-13 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py: import Set
2001-09-29 adustman <adustman@tweek.neosouth.net>
* setup.py: Catch more Linux platforms in the config.
2001-09-21 adustman <adustman@tweek.neosouth.net>
* setup.py: Solaris config (Bent NAgstrup Terp)
2001-09-20 adustman <adustman@tweek.neosouth.net>
* README: Good to update this at least once a year.
* CHANGELOG, MySQLdb/__init__.py, _mysql.c, setup.py:
Update to 0.9.1c2.
2001-09-13 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Fix exception handling in connect() (broken by 0.9.1.c1)
2001-09-12 adustman <adustman@tweek.neosouth.net>
* MANIFEST.in: Added CHANGELOG. (John Bowe)
2001-09-07 adustman <adustman@tweek.neosouth.net>
* setup.py:
OSX config (Paul DuBois); tab/space cleanups; more package info
* PKG-INFO: Generated by distutils.
* CHANGELOG: More stuff I forgot about.
* _mysql.c: Use two arg _PyTuple_Resize() for Python 2.2 and newer.
* setup.py: Version 0.9.1c1
* MySQLdb/converters.py: Return DECIMAL/NUMERIC as floating point.
2001-09-06 adustman <adustman@tweek.neosouth.net>
* CHANGELOG: Added a CHANGELOG, for people who like that sort of thing.
* _mysql.c:
Kill bastardly refcount bug that occurs starting with Python 2.0.1.
PyArgs_ParseTupleAndKeywords() returns borrowed references for O format
starting in 2.0.1, prior to that it returns new references, so it's
necessary to test the Python version to determine whether or not we
should Py_INCREF() it. If we always Py_INCREF() it, this produces a
memory leak in versions prior to 2.0.1.
* MySQLdb/__init__.py, _mysql.c, setup.py:
Change version number, back out memory changes.
* _mysql.c:
Memory allocation cleanups. Add missing newline in docstring.
2001-07-29 adustman <adustman@tweek.neosouth.net>
* _mysql.c: ER_PARSE_ERROR -> ProgrammingError;
#ifdef around some recent error types
2001-07-12 adustman <adustman@tweek.neosouth.net>
* _mysql.c: Fix leak on converter dictionary. (Ted Wright)
2001-07-11 adustman <adustman@tweek.neosouth.net>
* MANIFEST.in, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, PKG-INFO, _mysql.c, doc/MySQLdb.sgml, setup.py:
Minor fixes for 1.0.0.
2001-06-20 adustman <adustman@tweek.neosouth.net>
* doc/MySQLdb.sgml: Clarify use of host parameter to connect().
* doc/MySQLdb-FAQ.sgml, doc/MySQLdb.sgml:
Some corrections courtesy of Paul DuBois.
2001-06-04 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, _mysql.c, setup.py: Update version number.
2001-05-28 adustman <adustman@tweek.neosouth.net>
* .cvsignore, MySQLdb/.cvsignore, MySQLdb/constants/.cvsignore, doc/.cvsignore:
Ignore stuff.
2001-05-25 adustman <adustman@tweek.neosouth.net>
* MySQLdb/connections.py, _mysql.c, doc/MySQLdb.sgml, setup.py:
Rip out _mysql.field_*() methods, as MySQL recommends using SQL
instead. See C API docs.
2001-05-24 adustman <adustman@tweek.neosouth.net>
* PKG-INFO: Update version.
* MySQLdb/__init__.py, _mysql.c:
Clean up some import statements, bump versions to 0.9.0c2.
2001-05-23 adustman <adustman@tweek.neosouth.net>
* MySQLdb/times.py: Fix the case where there is no mx.DateTime.
* MySQLdb/connections.py: Remove a debug string.
* MANIFEST.in, MySQLdb/__init__.py, MySQLdb/connections.py, _mysql.c, _mysql_version.h, doc/MySQLdb.sgml, setup.cfg, setup.py:
0.9.0c1 minor edit.
2001-05-14 adustman <adustman@tweek.neosouth.net>
* _mysql.c: PyObject_Length() == -1 on error. Thanks, Jon Ribbens.
2001-05-12 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/converters.py, MySQLdb/data.py, MySQLdb/sets.py, MySQLdb/times.py, _mysql_version.h, setup.py:
Smash data into two separate modules: sets and times. I never liked
that name anyway.
Set has been extended somewhat. The comparision operators really only
work properly with Python 2.1, due to the limitations of __cmp__.
Set also uses the binary operators (&, |, ^), since these make somewhat
more sense than the arithmetic ones, though there is no good analog for
- (if only there were a nand operator...)
Bump the version to 0.9.0b3. This is not the actual 0.9.0b3 release yet,
however. I want to do some more insanity checking. But almost ready for
some candidate releases.
2001-05-11 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/data.py, doc/MySQLdb.sgml, _mysql_version.h, setup.py:
More major code heaving.
All the threading stuff is ripped out and burned.
Too much code for not enough benefit. Still thread-safe,
just don't share connections.
Made a nice Set class for SET columns.
Updated the docs.
2001-05-10 adustman <adustman@tweek.neosouth.net>
* doc/MySQLdb-FAQ.sgml, doc/MySQLdb.sgml: Revamped docs.
2001-05-09 adustman <adustman@tweek.neosouth.net>
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/constants/CLIENT.py, MySQLdb/constants/CR.py, MySQLdb/constants/ER.py, MySQLdb/constants/FIELD_TYPE.py, MySQLdb/constants/FLAG.py, MySQLdb/constants/REFRESH.py, MySQLdb/constants/__init__.py, MySQLdb/converters.py, MySQLdb/cursors.py, PKG-INFO, _mysql_exceptions.py, _mysql_version.h:
Initial import of 0.9.0 series (pre-1.0.0).
* MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/constants/CLIENT.py, MySQLdb/constants/CR.py, MySQLdb/constants/ER.py, MySQLdb/constants/FIELD_TYPE.py, MySQLdb/constants/FLAG.py, MySQLdb/constants/REFRESH.py, MySQLdb/constants/__init__.py, MySQLdb/converters.py, MySQLdb/cursors.py, PKG-INFO, _mysql_exceptions.py, _mysql_version.h:
New file.
* CompatMysqldb.py, MANIFEST.in, README, _mysql.c, setup.py:
Initial import of 0.9.0 series (pre-1.0.0).
* CompatMysqldb.py, MANIFEST.in, README, _mysql.c, setup.py: New file.

View File

@ -1,318 +0,0 @@
"""
Original author: James Henstridge <james@daa.com.au>
Adapted by: Andy Dustman <andy@dustman.net>
This is the original Mysqldb.py module which came with MySQLmodule-1.4,
only it has been adapted to use _mysql instead MySQL. It is intended
for backwards compatibility purposes only. But as a bonus, transactions
will work if your database server and table types support them. It is
called CompatMysqldb instead of Mysqldb so as not to interfere with an
existing Mysqldb, or MySQLdb on case-insensitive brain-dead operating
systems.
Under no circumstances should you bug James Henstridge about this!!!
-----
This is a class that implements an interface to mySQL databases, conforming
to the API published by the Python db-sig at
http://www.python.org/sigs/db-sig/DatabaseAPI.html
It is really just a wrapper for an older python interface to mySQL databases
called mySQL, which I modified to facilitate use of a cursor. That module was
Joseph Skinner's port of the mSQL module by David Gibson, which was a modified
version of Anthony Baxter's msql module.
As an example, to add some extra (unprivelledged) users to your database system,
and delete them again:
>>> import Mysqldb
>>> conn = Mysqldb.mysqldb('mysql@localhost root rootpasswd')
>>> curs = conn.cursor()
>>> curs.execute("insert into user (host, user) values ('%s', '%s')",
... [('localhost', 'linus'), ('somewhere.com.au', 'james')])
2
>>> curs.execute("select * from user")
>>> curs.fetchall()
-- record listing --
>>> curs.execute("delete from user where host = 'somewhere.com.au' or user = 'linus'")
2
>>> curs.close()
>>> conn.close()
The argument to mysqldb.mysqldb is of the form 'db@host user pass',
'db@host user', 'db@host', 'db', 'db user pass' or 'db user'.
As always, the source is a good manual :-)
James Henstridge <james@daa.com.au>
"""
import _mysql
MySQL = _mysql
from string import upper, split, join
error = 'mysqldb.error'
from MySQLdb.constants import FIELD_TYPE
_type_conv = { FIELD_TYPE.TINY: int,
FIELD_TYPE.SHORT: int,
FIELD_TYPE.LONG: long,
FIELD_TYPE.FLOAT: float,
FIELD_TYPE.DOUBLE: float,
FIELD_TYPE.LONGLONG: long,
FIELD_TYPE.INT24: int,
FIELD_TYPE.YEAR: int }
def isDDL(q):
return upper(split(q)[0]) in ('CREATE', 'ALTER', 'GRANT', 'REVOKE',
'DROP', 'SET')
def isDML(q):
return upper(split(q)[0]) in ('DELETE', 'INSERT', 'UPDATE', 'LOAD')
def isDQL(q):
return upper(split(q)[0]) in ('SELECT', 'SHOW', 'DESC', 'DESCRIBE')
class DBAPITypeObject:
def __init__(self,*values):
self.values = values
def __cmp__(self,other):
if other in self.values:
return 0
if other < self.values:
return 1
else:
return -1
_Set = DBAPITypeObject
STRING = _Set(FIELD_TYPE.CHAR, FIELD_TYPE.ENUM, FIELD_TYPE.INTERVAL,
FIELD_TYPE.SET, FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING)
BINARY = _Set(FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.MEDIUM_BLOB,
FIELD_TYPE.TINY_BLOB)
NUMBER = _Set(FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
FIELD_TYPE.TINY, FIELD_TYPE.YEAR)
DATE = _Set(FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE)
TIME = _Set(FIELD_TYPE.TIME)
TIMESTAMP = _Set(FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME)
ROWID = _Set()
class Connection:
"""This is the connection object for the mySQL database interface."""
def __init__(self, host, user, passwd, db):
from MySQLdb.constants import CLIENT
kwargs = {}
kwargs['conv'] = _type_conv
if host: kwargs['host'] = host
if user: kwargs['user'] = user
if passwd: kwargs['passwd'] = passwd
if db: kwargs['db'] = db
try:
self.__conn = apply(MySQL.connect, (), kwargs)
except MySQL.Error, msg:
raise error, msg
self.__curs = Cursor(self.__conn)
self.__transactional = self.__conn.server_capabilities & CLIENT.TRANSACTIONS
def __del__(self):
self.close()
def __getattr__(self, key):
return getattr(self.__curs, key)
def __setattr__(self, key, val):
if key in ('arraysize', 'description', 'insert_id'):
setattr(self.__curs, key, val)
else:
self.__dict__[key] = val
def close(self):
self.__conn = None
def cursor(self):
if self.__conn == None: raise error, "Connection is closed."
return Cursor(self.__conn)
def commit(self):
"""Commit the current transaction."""
if self.__transactional:
self.__conn.query("COMMIT")
def rollback(self):
"""Rollback the current transaction."""
if self.__transactional:
self.__conn.query("ROLLBACK")
else: raise error, "Not supported by server"
def callproc(self, params=None): pass
# These functions are just here so that every action that is
# covered by mySQL is covered by mysqldb. They are not standard
# DB API. The list* methods are not included, since they can be
# done with the SQL SHOW command.
def create(self, dbname):
"""This is not a standard part of Python DB API."""
self.__conn.query("CREATE DATABASE %s" % dbname)
self.__conn.store_result()
return None
def drop(self, dbname):
"""This is not a standard part of Python DB API."""
self.__conn.query("DROP DATABASE %s" % dbname)
self.__conn.store_result()
return None
def reload(self):
"""This is not a standard part of Python DB API."""
self.__conn.query("RELOAD TABLES")
self.__conn.store_result()
return None
def shutdown(self):
"""This is not a standard part of Python DB API."""
return self.__conn.shutdown()
class Cursor:
"""A cursor object for use with connecting to mySQL databases."""
def __init__(self, conn):
self.__conn = conn
self.__res = None
self.arraysize = 1
self.__dict__['description'] = None
self.__open = 1
self.insert_id = 0
def __del__(self):
self.close()
def __setattr__(self, key, val):
if key == 'description':
raise error, "description is a read-only attribute."
else:
self.__dict__[key] = val
def __delattr__(self, key):
if key in ('description', 'arraysize', 'insert_id'):
raise error, "%s can't be deleted." % (key,)
else:
del self.__dict__[key]
def close(self):
self.__conn = None
self.__res = None
self.__open = 0
def execute(self, op, params=None):
if not self.__open: raise error, "Cursor has been closed."
if params:
if type(params[0]) not in (type(()), type([])):
params = [params]
if isDDL(op):
self.__dict__['description'] = None
try:
for x in params:
self.__res = \
self.__conn.query(op % x)
self.insert_id = self.__res.insert_id()
except MySQL.Error, msg:
raise error, msg
return 1
if isDML(op):
self.__dict__['description'] = None
af = 0
try:
for x in params:
self.__res = \
self.__conn.query(op % x)
af =af+self.__res.affectedrows()
self.insert_id = self.__res.insert_id()
except MySQL.Error, msg:
raise error, msg
return af
if isDQL(op):
try:
self.__res = self.__conn.query(
op % params[-1])
self.insert_id = self.__res.insert_id()
except MySQL.Error, msg:
raise error, msg
self.__dict__['description'] = self.__res.describe()
return None
else:
try:
self.__conn.query(op)
self.__res = self.__conn.store_result()
self.insert_id = self.__conn.insert_id()
except MySQL.Error, msg:
raise error, msg
self.__dict__['description'] = None
if isDDL(op):
return 1
elif self.__conn.affected_rows() != -1:
return self.__conn.affected_rows()
else:
self.__dict__['description'] = self.__res.describe()
return None
def fetchone(self):
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(1)[0]
except MySQL.Error, msg:
raise error, msg
def fetchmany(self, size=None):
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(size or self.arraysize)
except MySQL.Error, msg:
raise error, msg
def fetchall(self):
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(0)
except MySQL.Error, msg:
raise error, msg
def fetchoneDict(self):
"""This is not a standard part of Python DB API."""
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(1, 2)[0]
except MySQL.Error, msg:
raise error, msg
def fetchmanyDict(self, size=None):
"""This is not a standard part of Python DB API."""
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(size or self.arraysize, 2)
except MySQL.Error, msg:
raise error, msg
def fetchallDict(self):
"""This is not a standard part of Python DB API."""
if not self.__res: raise error, "no query made yet."
try:
return self.__res.fetch_row(0,2)
except MySQL.Error, msg:
raise error, msg
def setinputsizes(self, sizes): pass
def setoutputsize(self, size, col=None): pass
def mysqldb(connect_string):
"""Makes a connection to the MySQL server. The Argument should be of
the form 'db@host user pass' or 'db@host user' or 'db@host' or 'db'
or 'db user pass' or 'db user', where db is the database name, host
is the server's host name, user is your user name, and pass is your
password."""
val = split(connect_string)
if len(val) == 0: raise error, "no database specified"
while len(val) < 3: val.append('')
dh = split(val[0], '@')
if len(dh) == 0: raise error, "no database specified"
while len(dh) < 2: dh.append('')
return Connection(dh[1], val[1], val[2], dh[0])

View File

@ -18,7 +18,7 @@ __revision__ = """$Revision$"""[11:-2]
version_info = ( version_info = (
1, 1,
1, 1,
6, 7,
"final", "final",
1) 1)
if version_info[3] == "final": __version__ = "%d.%d.%d" % version_info[:3] if version_info[3] == "final": __version__ = "%d.%d.%d" % version_info[:3]

View File

@ -1,5 +1,5 @@
#define version_info "(1,1,6,'final',1)" #define version_info "(1,1,7,'final',1)"
#define __version__ "1.1.6" #define __version__ "1.1.7"
/* /*
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

622
MySQLdb/doc/MySQLdb.txt Normal file
View File

@ -0,0 +1,622 @@
====================
MySQLdb User's Guide
====================
Introduction
------------
MySQLdb is an thread-compatible interface to the popular MySQL
database server that provides the Python database API.
Installation
------------
The ``README`` file has complete installation instructions.
_mysql
------
If you want to write applications which are portable across databases,
use MySQLdb_, and avoid using this module directly. ``_mysql``
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 MySQLdb module. If you really need it, use the
standard MySQL docs and transliterate as necessary.
.. _`MySQL documentation`: http://dev.mysql.com/doc/mysql/en/index.html
MySQL C API translation
.......................
The MySQL C API has been wrapped in an object-oriented way. The only
MySQL data structures which are implemented are the ``MYSQL``
(database connection handle) and ``MYSQL_RES`` (result handle)
types. In general, any function which takes ``MYSQL *mysql`` as an
argument is now a method of the connection object, and any function
which takes ``MYSQL_RES *result`` 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 ``mysql_``
prefix is dropped from the name. Most of the ``conn`` methods listed
are also available as MySQLdb Connection object methods. Their use is
non-portable.
MySQL C API function mapping
............................
================================= ==================================
C API ``_mysql``
================================= ==================================
``mysql_affected_rows()`` ``conn.affected_rows()``
``mysql_close()`` ``conn.close()``
``mysql_connect()`` ``_mysql.connect()``
``mysql_data_seek()`` ``result.data_seek()``
``mysql_debug()`` ``_mysql.debug()``
``mysql_dump_debug_info`` ``conn.dump_debug_info()``
``mysql_escape_string()`` ``_mysql.escape_string()``
``mysql_fetch_row()`` ``result.fetch_row()``
``mysql_get_client_info()`` ``_mysql.get_client_info()``
``mysql_get_host_info()`` ``conn.get_host_info()``
``mysql_get_proto_info()`` ``conn.get_proto_info()``
``mysql_get_server_info()`` ``conn.get_server_info()``
``mysql_info()`` ``conn.info()``
``mysql_insert_id()`` ``conn.insert_id()``
``mysql_num_fields()`` ``result.num_fields()``
``mysql_num_rows()`` ``result.num_rows()``
``mysql_options()`` ``_mysql.connect()``
``mysql_ping()`` ``conn.ping()``
``mysql_query()`` ``conn.query()``
``mysql_real_connect()`` ``_mysql.connect()``
``mysql_real_query()`` ``conn.query()``
``mysql_real_escape_string()`` ``conn.escape_string()``
``mysql_row_seek()`` ``result.row_seek()``
``mysql_row_tell()`` ``result.row_tell()``
``mysql_select_db()`` ``conn.select_db()``
``mysql_stat()`` ``conn.stat()``
``mysql_store_result()`` ``conn.store_result()``
``mysql_thread_id()`` ``conn.thread_id()``
``mysql_thread_safe_client()`` ``conn.thread_safe_client()``
``mysql_use_result()`` ``conn.use_result()``
``CLIENT_*`` ``MySQLdb.constants.CLIENT.*``
``CR_*`` ``MySQLdb.constants.CR.*``
``ER_*`` ``MySQLdb.constants.ER.*``
``FIELD_TYPE_*`` ``MySQLdb.constants.FIELD_TYPE.*``
``FLAG_*`` ``MySQLdb.constants.FLAG.*``
================================= ==================================
Some _mysql examples
....................
Okay, so you want to use ``_mysql`` anyway. Here are some examples.
The simplest possible database connection is::
import _mysql
db=_mysql.connect()
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 ``USE`` a database. Chances are you need to supply more
information.::
db=_mysql.connect("localhost","joebob","moonpie","thangs")
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".
We haven't even begun to touch upon all the parameters ``connect()``
can take. For this reason, I prefer to use keyword parameters::
db=_mysql.connect(host="localhost",user="joebob",
passwd="moonpie",db="thangs")
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::
db=_mysql.connect(passwd="moonpie",db="thangs")
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)::
db=_mysql.connect(host="outhouse",port=3307,passwd="moonpie",db="thangs")
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.
Generally speaking, putting passwords in your code is not such a good
idea::
db=_mysql.connect(host="outhouse",db="thangs",read_default_file="~/.my.cnf")
This does what the previous example does, but gets the username and
password and other parameters from ~/.my.cnf (UNIX-like systems). Read
about `option files`_ for more details.
.. _`option files`: http://dev.mysql.com/doc/mysql/en/Option_files.html
So now you have an open connection as ``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
``db.query()``::
db.query("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < 5""")
There's no return value from this, but exceptions can be raised. The
exceptions are defined in a separate module, ``_mysql_exceptions``,
but ``_mysql`` exports them. Read DB API specification PEP-249_ to
find out what they are, or you can use the catch-all ``MySQLError``.
.. _PEP-249: http://www.python.org/peps/pep-0249.html
At this point your query has been executed and you need to get the
results. You have two options::
r=db.store_result()
# ...or...
r=db.use_result()
Both methods return a result object. What's the difference?
``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 ``LIMIT`` clause to your
query, to limit the number of rows returned. The other is to use
``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 **all** the rows. Generally I
recommend using ``store_result()`` unless your result set is really
huge and you can't use ``LIMIT`` for some reason.
Now, for actually getting real results::
>>> r.fetch_row()
(('3','2','0'),)
This might look a little odd. The first thing you should know is,
``fetch_row()`` takes some additional parameters. The first one is,
how many rows (``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 ``maxrows=0``, it returns all rows of the result
set. If you ever get an empty tuple back, you ran out of rows.
The second parameter (``how``) tells it how the row should be
represented. By default, it is zero which means, return as a tuple.
``how=1`` means, return it as a dictionary, where the keys are the
column names, or ``table.column`` if there are two columns with the
same name (say, from a join). ``how=2`` means the same as ``how=1``
except that the keys are *always* ``table.column``; this is for
compatibility with the old ``Mysqldb`` module.
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 ``maxrows``.
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, ``_mysql`` can do this for you. (And ``MySQLdb``
does do this for you.) To have automatic type conversion done, you
need to create a type converter dictionary, and pass this to
``connect()`` as the ``conv`` keyword parameter.
The keys of ``conv`` should be MySQL column types, which in the
C API are ``FIELD_TYPE_*``. You can get these values like this::
from MySQLdb.constants import FIELD_TYPE
By default, any column type that can't be found in ``conv`` is
returned as a string, which works for a lot of stuff. For our
purposes, we probably want this::
my_conv = { FIELD_TYPE.LONG: int }
This means, if it's a ``FIELD_TYPE_LONG``, call the builtin ``int()``
function on it. Note that ``FIELD_TYPE_LONG`` is an ``INTEGER``
column, which corresponds to a C ``long``, which is also the type used
for a normal Python integer. But beware: If it's really an ``UNSIGNED
INTEGER`` column, this could cause overflows. For this reason,
``MySQLdb`` actually uses ``long()`` to do the conversion. But we'll
ignore this potential problem for now.
Then if you use ``db=_mysql.connect(conv=my_conv...)``, the
results will come back ``((3, 2, 0),)``, which is what you would
expect.
MySQLdb
-------
MySQLdb is a thin Python wrapper around ``_mysql`` 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 ``_mysql``
for the sake of efficiency.
The DB API specification PEP-249_ should be your primary guide for
using this module. Only deviations from the spec and other
database-dependent things will be documented here.
Functions and attributes
........................
Only a few top-level functions and attributes are defined within
MySQLdb.
connect(parameters...)
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
``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:
host
name of host to connect to. Default: use the local host
via a UNIX socket (where applicable)
user
user to authenticate as. Default: current effective user.
passwd
password to authenticate with. Default: no password.
db
database to use. Default: no default database.
port
TCP port of MySQL server. Default: standard port (3306).
unix_socket
location of UNIX socket. Default: use default location or
TCP for remote hosts.
conv
type conversion dictionary. Default: a copy of
``MySQLdb.converters.conversions``
compress
Enable protocol compression. Default: no compression.
connect_timeout
Abort if connect is not completed within
given number of seconds. Default: no timeout (?)
named_pipe
Use a named pipe (Windows). Default: don't.
init_command
Initial command to issue to server upon
connection. Default: Nothing.
read_default_file
MySQL configuration file to read; see
the MySQL documentation for ``mysql_options()``.
read_default_group
Default group to read; see the MySQL
documentation for ``mysql_options()``.
cursorclass
cursor class that ``cursor()`` uses, unless
overridden. Default: ``MySQLdb.cursors.Cursor``. *This
must be a keyword parameter.*
unicode
If set, CHAR and VARCHAR columns are returned as Unicode
strings, using the specified character set. None means to
use a default encoding. *This must be a keyword
parameter.*
unicode_errors
If set, this is used as the errors parameter to the
``unicode()`` function. Default: "strict". *This must be a
keyword parameter.*
ssl
This parameter takes a dictionary or mapping, where the
keys are parameter names used by the mysql_ssl_set_ MySQL
C API call. If this is set, it initiates an SSL connection
to the server; if there is no SSL support in the client,
an exception is raised. *This must be a keyword
parameter.*
.. _mysql_ssl_set: http://dev.mysql.com/doc/mysql/en/mysql_ssl_set.html
apilevel
String constant stating the supported DB API level. '2.0'
threadsafety
Integer constant stating the level of thread safety the
interface supports. This is set to 1, which means: Threads may
share the module.
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 ``mysql_store_result()``), it is complicated by
SSCursor (which uses ``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 ``COMMIT`` or ``ROLLBACK`` is executed by
the Connection object. Two threads simply 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.
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.
For threaded applications, try using a connection pool.
This can be done using the `Pool module`_.
.. _`Pool module`: http://dustman.net/andy/python/Pool
paramstyle
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.
Note that any literal percent signs in the query string passed
to execute() must be escaped, i.e. %%.
Parameter placeholders can **only** be used to insert column
values. They can **not** be used for other parts of SQL, such as
table names, statements, etc.
conv
A dictionary or mapping which controls how types are converted
from MySQL to Python and vice versa.
If the key is a MySQL type (from ``FIELD_TYPE.*``), then the value
can be either:
* a callable object which takes a string argument (the MySQL
value),' returning a Python value
* a sequence of 2-tuples, where the first value is a combination
of flags from ``MySQLdb.constants.FLAG``, and the second value
is a function as above. The sequence is tested until the flags
on the field match those of the first value. If both values
are None, then the default conversion is done. Presently this
is only used to distinquish TEXT and BLOB columns.
If the key is a Python type or class, then the value is a
callable Python object (usually a function) taking two arguments
(value to convert, and the conversion dictionary) which converts
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 ``MySQLdb.converters.conversions``. Several
non-standard types are returned as strings, which is how MySQL
returns all columns. For more details, see the built-in module
documentation.
Connection Objects
..................
Connection objects are returned by the ``connect()`` function.
commit()
If the database and the tables support transactions, this
commits the current transaction; otherwise this method
successfully does nothing.
rollback()
If the database and tables support transactions, this rolls back
(cancels) the current transaction; otherwise a
``NotSupportedError`` is raised.
cursor([cursorclass])
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
``Cursor`` class. Also see the additional supplied cursor
classes in the usage section.
There are many more methods defined on the connection object which
are MySQL-specific. For more information on them, consult the internal
documentation using ``pydoc``.
Cursor Objects
..............
callproc()
Not implemented.
close()
Closes the cursor. Future operations raise ``ProgrammingError``.
If you are using server-side cursors, it is very important to
close the cursor when you are done with it and before creating a
new one.
insert_id()
Returns the last ``AUTO_INCREMENT`` field value inserted
into the database. (Non-standard)
info()
Returns some information about the last query. Normally
you don't need to check this. With the default cursor, any MySQL
warnings cause ``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 ``mysql_info()``. (Non-standard)
setinputsizes()
Does nothing, successfully.
setoutputsizes()
Does nothing, successfully.
nextset()
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 doesn't support multiple result sets until 4.1;
there is currently no support for this in MySQLdb.
Some examples
.............
The ``connect()`` method works nearly the same as with `_mysql`_::
import MySQLdb
db=MySQLdb.connect(passwd="moonpie",db="thangs")
To perform a query, you first need a cursor, and then you can execute
queries on it::
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))
In this example, ``max_price=5`` Why, then, use ``%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".
Why the tuple? Because the DB API requires you to pass in any
parameters as a sequence.
And now, the results::
>>> c.fetchone()
(3L, 2L, 0L)
Quite unlike the ``_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?
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.
If you wanted more rows, you could use ``c.fetchmany(n)`` or
``c.fetchall()``. These do exactly what you think they do. On
``c.fetchmany(n)``, the ``n`` is optional and defaults to
``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.
Note that in contrast to the above, ``c.fetchone()`` returns ``None``
when there are no more rows to fetch.
The only other method you are very likely to use is when you have to
do a multi-row insert::
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 )
] )
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
``%s``. And also note that we only included format strings for one
row. MySQLdb picks those out and duplicates them for each row.
Using and extending
-------------------
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
``connect()`` 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.
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:
BaseCursor
The base class for Cursor objects. This does not raise Warnings.
CursorStoreResultMixIn
Causes the Cursor to use the ``mysql_store_result()`` function to
get the query result. The entire result set is stored on the
client side.
CursorUseResultMixIn
Causes the cursor to use the ``mysql_use_result()`` function to
get the query result. The result set is stored on the server side
and is transferred row by row using fetch operations.
CursorTupleRowsMixIn
Causes the cursor to return rows as a tuple of the column values.
CursorDictRowsMixIn
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
``table.column``. This can be avoided by using the SQL ``AS``
keyword. (This is yet-another reason not to use ``*`` in SQL
queries, particularly where ``JOIN`` is involved.)
Cursor
The default cursor class. This class is composed of
``CursorWarningMixIn``, ``CursorStoreResultMixIn``,
``CursorTupleRowsMixIn,`` and ``BaseCursor``, i.e. it raises
``Warning``, uses ``mysql_store_result()``, and returns rows as
tuples.
DictCursor
Like ``Cursor`` except it returns rows as dictionaries.
SSCursor
A "server-side" cursor. Like ``Cursor`` but uses
``CursorUseResultMixIn``. Use only if you are dealing with
potentially large result sets.
SSDictCursor
Like ``SSCursor`` except it returns rows as dictionaries.
:Title: MySQLdb: a Python interface for MySQL
:Author: Andy Dustman
:Version: $Revision$

View File

@ -2,7 +2,8 @@
"""Setup script for the MySQLdb module distribution.""" """Setup script for the MySQLdb module distribution."""
import os, sys import os
import sys
from distutils.core import setup from distutils.core import setup
from distutils.extension import Extension from distutils.extension import Extension
@ -18,7 +19,7 @@ embedded_server = (mysqlclient == 'mysqld')
name = "MySQL-%s" % os.path.basename(sys.executable) name = "MySQL-%s" % os.path.basename(sys.executable)
if embedded_server: if embedded_server:
name = name + "-embedded" name = name + "-embedded"
version = "1.1.6" version = "1.1.7"
# include files and library locations should cover most platforms # include files and library locations should cover most platforms
include_dirs = [ include_dirs = [
@ -87,7 +88,11 @@ elif os.name == "posix": # UNIX-ish platforms not covered above
else: else:
raise "UnknownPlatform", "sys.platform=%s, os.name=%s" % \ raise "UnknownPlatform", "sys.platform=%s, os.name=%s" % \
(sys.platform, os.name) (sys.platform, os.name)
# avoid frightening noobs with warnings about missing directories
include_dirs = [ d for d in include_dirs if os.path.isdir(d) ]
library_dirs = [ d for d in library_dirs if os.path.isdir(d) ]
long_description = \ long_description = \
"""Python interface to MySQL """Python interface to MySQL