mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 19:31:54 +08:00
Update docs.
result.fetch_row(0,how) returns all rows of the rsult set as a tuple.
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
#author: James Henstridge <james@daa.com.au>
|
#author: James Henstridge <james@daa.com.au>
|
||||||
#adapted to _mysql by Andy Dustman <adustman@comstar.net>
|
#adapted to _mysql by Andy Dustman <andy@dustman.net>
|
||||||
|
#under no circumstances should you bug James about this!!!
|
||||||
|
|
||||||
"""This is a class that implements an interface to mySQL databases, conforming
|
"""This is a class that implements an interface to mySQL databases, conforming
|
||||||
to the API published by the Python db-sig at
|
to the API published by the Python db-sig at
|
||||||
@ -41,21 +42,10 @@ from string import upper, split, join
|
|||||||
|
|
||||||
error = 'mysqldb.error'
|
error = 'mysqldb.error'
|
||||||
|
|
||||||
_type = {}
|
|
||||||
for a in ('char', 'varchar', 'string', 'unhandled', '????'):
|
|
||||||
_type[a] = 'STRING'
|
|
||||||
for a in ('tiny blob', 'medium blob', 'long blob', 'blob'):
|
|
||||||
_type[a] = 'RAW'
|
|
||||||
for a in ('short', 'long', 'float', 'double', 'decimal'):
|
|
||||||
_type[a] = 'NUMBER'
|
|
||||||
for a in ('date', 'time', 'datetime', 'timestamp'):
|
|
||||||
_type[a] = 'DATE'
|
|
||||||
del a
|
|
||||||
|
|
||||||
from _mysql import FIELD_TYPE
|
from _mysql import FIELD_TYPE
|
||||||
_type_conv = { FIELD_TYPE.TINY: int,
|
_type_conv = { FIELD_TYPE.TINY: int,
|
||||||
FIELD_TYPE.SHORT: int,
|
FIELD_TYPE.SHORT: int,
|
||||||
FIELD_TYPE.LONG: int,
|
FIELD_TYPE.LONG: long,
|
||||||
FIELD_TYPE.FLOAT: float,
|
FIELD_TYPE.FLOAT: float,
|
||||||
FIELD_TYPE.DOUBLE: float,
|
FIELD_TYPE.DOUBLE: float,
|
||||||
FIELD_TYPE.LONGLONG: long,
|
FIELD_TYPE.LONGLONG: long,
|
||||||
@ -70,6 +60,33 @@ def isDML(q):
|
|||||||
def isDQL(q):
|
def isDQL(q):
|
||||||
return upper(split(q)[0]) in ('SELECT', 'SHOW', 'DESC', 'DESCRIBE')
|
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:
|
class Connection:
|
||||||
"""This is the connection object for the mySQL database interface."""
|
"""This is the connection object for the mySQL database interface."""
|
||||||
def __init__(self, host, user, passwd, db):
|
def __init__(self, host, user, passwd, db):
|
||||||
@ -84,9 +101,10 @@ class Connection:
|
|||||||
except MySQL.Error, msg:
|
except MySQL.Error, msg:
|
||||||
raise error, msg
|
raise error, msg
|
||||||
self.__curs = Cursor(self.__conn)
|
self.__curs = Cursor(self.__conn)
|
||||||
self._server_info = i = self.__conn.get_server_info()
|
self.__conn.query("SHOW VARIABLES")
|
||||||
self._server_version = int(i[0])*10000 + int(i[2:4])*100 + int(i[5:7])
|
self.__vars = {}
|
||||||
|
for k, v in self.__conn.store_result().fetch_row(0):
|
||||||
|
self.__vars[k] = v
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.close()
|
self.close()
|
||||||
@ -109,14 +127,15 @@ class Connection:
|
|||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
"""Commit the current transaction."""
|
"""Commit the current transaction."""
|
||||||
if self._server_version > 32315: self.__conn.query("COMMIT")
|
if self.__vars.get('have_bdb', 'NO') == 'YES':
|
||||||
|
self.__conn.query("COMMIT")
|
||||||
|
|
||||||
def rollback(self):
|
def rollback(self):
|
||||||
"""Rollback the current transaction."""
|
"""Rollback the current transaction."""
|
||||||
if self._server_version > 32315: self.__conn.query("ROLLBACK")
|
if self.__vars.get('have_bdb', 'NO') == 'YES':
|
||||||
|
self.__conn.query("ROLLBACK")
|
||||||
else: raise error, "Not supported by server"
|
else: raise error, "Not supported by server"
|
||||||
|
|
||||||
|
|
||||||
def callproc(self, params=None): pass
|
def callproc(self, params=None): pass
|
||||||
|
|
||||||
# These functions are just here so that every action that is
|
# These functions are just here so that every action that is
|
||||||
@ -205,12 +224,9 @@ class Cursor:
|
|||||||
self.__res = self.__conn.query(
|
self.__res = self.__conn.query(
|
||||||
op % params[-1])
|
op % params[-1])
|
||||||
self.insert_id = self.__res.insert_id()
|
self.insert_id = self.__res.insert_id()
|
||||||
f = self.__res.fields()
|
|
||||||
except MySQL.Error, msg:
|
except MySQL.Error, msg:
|
||||||
raise error, msg
|
raise error, msg
|
||||||
self.__dict__['description'] = tuple(map(
|
self.__dict__['description'] = self.__res.describe()
|
||||||
lambda x: (x[0], _type[x[2]], x[3],
|
|
||||||
x[3]), f))
|
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -244,17 +260,10 @@ class Cursor:
|
|||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
if not self.__res: raise error, "no query made yet."
|
if not self.__res: raise error, "no query made yet."
|
||||||
try:
|
try:
|
||||||
rows = r = list(self.__res.fetch_row(self.arraysize))
|
return self.__res.fetch_row(0)
|
||||||
while 1:
|
|
||||||
rows = list(self.__res.fetch_row(self.arraysize))
|
|
||||||
if not rows: break
|
|
||||||
r.extend(rows)
|
|
||||||
return r
|
|
||||||
except MySQL.Error, msg:
|
except MySQL.Error, msg:
|
||||||
raise error, msg
|
raise error, msg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def fetchoneDict(self):
|
def fetchoneDict(self):
|
||||||
"""This is not a standard part of Python DB API."""
|
"""This is not a standard part of Python DB API."""
|
||||||
if not self.__res: raise error, "no query made yet."
|
if not self.__res: raise error, "no query made yet."
|
||||||
@ -275,17 +284,10 @@ class Cursor:
|
|||||||
"""This is not a standard part of Python DB API."""
|
"""This is not a standard part of Python DB API."""
|
||||||
if not self.__res: raise error, "no query made yet."
|
if not self.__res: raise error, "no query made yet."
|
||||||
try:
|
try:
|
||||||
rows = r = list(self.__res.fetch_row(self.arraysize, 2))
|
return self.__res.fetch_row(0,2)
|
||||||
while 1:
|
|
||||||
rows = list(self.__res.fetch_row(self.arraysize, 2))
|
|
||||||
if not rows: break
|
|
||||||
r.extend(rows)
|
|
||||||
return r
|
|
||||||
except MySQL.Error, msg:
|
except MySQL.Error, msg:
|
||||||
raise error, msg
|
raise error, msg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setinputsizes(self, sizes): pass
|
def setinputsizes(self, sizes): pass
|
||||||
def setoutputsize(self, size, col=None): pass
|
def setoutputsize(self, size, col=None): pass
|
||||||
|
|
||||||
|
@ -19,9 +19,7 @@ You have two basic options:
|
|||||||
<p>
|
<p>
|
||||||
<enum>
|
<enum>
|
||||||
<item>
|
<item>
|
||||||
Modify the compiler flags in Setup so that it links against the static
|
Modify setup.py so that it links against the static library; see the comments.
|
||||||
library. Probably <tt/-static/ will do this for gcc/egcs; YMMV for
|
|
||||||
other C compilers.
|
|
||||||
<item>
|
<item>
|
||||||
Change your system environment so that the MySQL libraries are on
|
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
|
your loader path. With Linux, you can modify <tt>/etc/ld.so.conf</tt> (see
|
||||||
@ -38,13 +36,13 @@ linking against an earlier version. You may also have more than one version
|
|||||||
installed. Get Python 1.5.2 from your vendor or python.org.
|
installed. Get Python 1.5.2 from your vendor or python.org.
|
||||||
|
|
||||||
<sect1>ImportError: ./_mysqlmodule.so: undefined symbol: uncompress
|
<sect1>ImportError: ./_mysqlmodule.so: undefined symbol: uncompress
|
||||||
<sect1>./_mysqlmodule.c:33: mysql.h: No such file or directory
|
|
||||||
<P>
|
<P>
|
||||||
It seems that MySQL-3.23 client libraries require libz for gzip
|
It seems that MySQL-3.23 client libraries require libz for gzip
|
||||||
compression. Add -lz to the link line in Setup.
|
compression. setup.py should add this automatically.
|
||||||
|
|
||||||
|
<sect1>./_mysqlmodule.c:33: mysql.h: No such file or directory
|
||||||
<P>The include path (-I) to your MySQL include files is wrong; modify
|
<P>The include path (-I) to your MySQL include files is wrong; modify
|
||||||
Setup. OR: You don't have the MySQL development stuff loaded. If you
|
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
|
are using the Red Hat RPMs, you need the <tt/MySQL-devel/ RPM to compile
|
||||||
<tt/_mysqlmodule.so/. However, if you link against the static MySQL
|
<tt/_mysqlmodule.so/. However, if you link against the static MySQL
|
||||||
libraries (see above), you can install <tt/_mysqlmodule.so/ on a system
|
libraries (see above), you can install <tt/_mysqlmodule.so/ on a system
|
||||||
@ -52,21 +50,21 @@ that does not have the MySQL client libraries (<tt/libmysqlclient/).
|
|||||||
|
|
||||||
<sect1>I'm using Windows...
|
<sect1>I'm using Windows...
|
||||||
<P>Say no more.
|
<P>Say no more.
|
||||||
<P>There is a <tt/compile.py/ script which supposedly gets the job done
|
<P>I don't use Windows. setup.py is supposed to work for building.
|
||||||
for Windows, but I can't test it.
|
There may also be a link to some user-contributed binaries on the web site.
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect>
|
<sect>
|
||||||
Trouble with ZMySQLDA
|
Trouble with ZMySQLDA
|
||||||
<p>Not supported. By me, at least. There is a new version on
|
<p>What? ZMySQLDA never fails! Well, actually, I just don't have any
|
||||||
<htmlurl url="http://www.zope.org" name="www.zope.org">
|
good questions yet. Except: Install MySQLdb first, and then untar
|
||||||
that supports MySQLdb without any patching. Use that.
|
the ZMySQLDA source into your Zope home, and restart Zope.
|
||||||
<sect>Using MySQLdb
|
<sect>Using MySQLdb
|
||||||
<p>
|
<p>
|
||||||
MySQLdb is a
|
MySQLdb is a
|
||||||
<htmlurl url="http://www.python.org/topics/database/DatabaseAPI-2.0.html"
|
<htmlurl url="http://www.python.org/topics/database/DatabaseAPI-2.0.html"
|
||||||
name="Python Database API Specification 2.0"> database module, so you
|
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
|
should be familiar with the spec. Deviations from the spec are documented in the
|
||||||
<htmlurl url="http://starship.python.net/crew/adustman/MySQLdb.html"
|
<htmlurl url="http://dustman.net/andy/python/MySQLdb/doc/MySQLdb.html"
|
||||||
name="MySQLdb documentation">.
|
name="MySQLdb documentation">.
|
||||||
<sect1>What do I do if I am completely clueless?
|
<sect1>What do I do if I am completely clueless?
|
||||||
<p>Get a clue. Clues have been provided in the <tt/examples/ directory
|
<p>Get a clue. Clues have been provided in the <tt/examples/ directory
|
||||||
@ -97,18 +95,15 @@ results = c.fetchall()
|
|||||||
</code>
|
</code>
|
||||||
<sect1>But MySQL doesn't have cursors!
|
<sect1>But MySQL doesn't have cursors!
|
||||||
<p>True enough. MySQLdb fakes it, though, because the spec requires it.
|
<p>True enough. MySQLdb fakes it, though, because the spec requires it.
|
||||||
<sect1>cursor.rollback() is missing!
|
<sect1>cursor.rollback() always fails!
|
||||||
<p>MySQL doesn't do transactions. <tt/cursor.rollback()/ is supposed to
|
<p>MySQL now supports transactions using BDB tables.
|
||||||
roll back (cancel) the current transaction. If you really need to do
|
If your server doesn't support them, rollbacks will always fail, as they should,
|
||||||
this, then you definitely want <tt/cursor.rollback()/ to fail, because
|
because it can't do what you asked.
|
||||||
it can't do what you want it to do.
|
Even if your server does support them, rollbacks will fail if you
|
||||||
|
modified any non-BDB tables.
|
||||||
<p>OTOH, <tt/cursor.commit()/, which attempts to commit the transaction
|
<p>OTOH, <tt/cursor.commit()/, which attempts to commit the transaction
|
||||||
to the database, <em/does/ exist and always succeeds, because MySQL
|
to the database, <em/does/ exist and always succeeds, because MySQL
|
||||||
essentially is always in auto-commit mode.
|
essentially is always in auto-commit mode.
|
||||||
<p>MySQL-3.23 will, sometime in the near future, support transactions.
|
|
||||||
When this happens, <tt/cursor.commit()/ will actually do something
|
|
||||||
(and may fail if MySQL returns an error or warning condition), and
|
|
||||||
<tt/cursor.rollback()/ will actually exist and undo the current transaction.
|
|
||||||
<sect1>How do I use some of the special MySQL features?
|
<sect1>How do I use some of the special MySQL features?
|
||||||
<P>Short answer: Don't, if you can avoid it. Your program will not
|
<P>Short answer: Don't, if you can avoid it. Your program will not
|
||||||
be portable to other databases.
|
be portable to other databases.
|
||||||
@ -119,7 +114,7 @@ argument (the connection handle in the C API). So let's say you want to
|
|||||||
use <tt/mysql_select_db(newdb)/. In MySQLdb, that's
|
use <tt/mysql_select_db(newdb)/. In MySQLdb, that's
|
||||||
<tt/db.select_db(newdb)/ where <tt/db/ is your Connection object.
|
<tt/db.select_db(newdb)/ where <tt/db/ is your Connection object.
|
||||||
<sect1>I still wanna use _mysql directly.
|
<sect1>I still wanna use _mysql directly.
|
||||||
<p>Well, it <tt/may/ be appropriate in some cirumstances. The patched
|
<p>Well, it <tt/may/ be appropriate in some cirumstances.
|
||||||
ZMySQLDA does this, because MySQLdb does a lot of type conversion that
|
ZMySQLDA does this, because MySQLdb does a lot of type conversion that
|
||||||
isn't necessary for Zope's purposes.
|
isn't necessary for Zope's purposes.
|
||||||
<enum>
|
<enum>
|
||||||
|
@ -53,7 +53,7 @@ quote_conv = { types.IntType: Thing2Str,
|
|||||||
|
|
||||||
type_conv = { FIELD_TYPE.TINY: int,
|
type_conv = { FIELD_TYPE.TINY: int,
|
||||||
FIELD_TYPE.SHORT: int,
|
FIELD_TYPE.SHORT: int,
|
||||||
FIELD_TYPE.LONG: int,
|
FIELD_TYPE.LONG: long,
|
||||||
FIELD_TYPE.FLOAT: float,
|
FIELD_TYPE.FLOAT: float,
|
||||||
FIELD_TYPE.DOUBLE: float,
|
FIELD_TYPE.DOUBLE: float,
|
||||||
FIELD_TYPE.LONGLONG: long,
|
FIELD_TYPE.LONGLONG: long,
|
||||||
@ -144,14 +144,6 @@ def Binary(x): return str(x)
|
|||||||
|
|
||||||
insert_values = re.compile(r'values\s(\(.+\))', re.IGNORECASE)
|
insert_values = re.compile(r'values\s(\(.+\))', re.IGNORECASE)
|
||||||
|
|
||||||
def _fetchall(result, *args):
|
|
||||||
rows = r = list(apply(result.fetch_row, args))
|
|
||||||
while 1:
|
|
||||||
rows = apply(result.fetch_row, args)
|
|
||||||
if not rows: break
|
|
||||||
r.extend(list(rows))
|
|
||||||
return r
|
|
||||||
|
|
||||||
class BaseCursor:
|
class BaseCursor:
|
||||||
|
|
||||||
"""A base for Cursor classes. Useful attributes:
|
"""A base for Cursor classes. Useful attributes:
|
||||||
@ -256,6 +248,14 @@ class BaseCursor:
|
|||||||
|
|
||||||
def nextset(self): return None
|
def nextset(self): return None
|
||||||
|
|
||||||
|
def _fetch_row(self): return self._result.fetch_row(1, self._fetch_type)[0]
|
||||||
|
|
||||||
|
def _fetch_rows(self, size):
|
||||||
|
return self._result.fetch_row(size, self._fetch_type)
|
||||||
|
|
||||||
|
def _fetch_all_rows(self):
|
||||||
|
return self._result.fetch_row(0, self._fetch_type)
|
||||||
|
|
||||||
|
|
||||||
class CursorWarningMixIn:
|
class CursorWarningMixIn:
|
||||||
|
|
||||||
@ -363,16 +363,8 @@ class CursorTupleRowsMixIn:
|
|||||||
|
|
||||||
_fetch_type = 0
|
_fetch_type = 0
|
||||||
|
|
||||||
def _fetch_row(self): return self._result.fetch_row(1, self._fetch_type)[0]
|
|
||||||
|
|
||||||
def _fetch_rows(self, size):
|
class CursorDictRowsMixIn:
|
||||||
return self._result.fetch_row(size, self._fetch_type)
|
|
||||||
|
|
||||||
def _fetch_all_rows(self):
|
|
||||||
return _fetchall(self._result, self.arraysize, self._fetch_type)
|
|
||||||
|
|
||||||
|
|
||||||
class CursorDictRowsMixIn(CursorTupleRowsMixIn):
|
|
||||||
|
|
||||||
_fetch_type = 1
|
_fetch_type = 1
|
||||||
|
|
||||||
@ -453,9 +445,11 @@ class Connection:
|
|||||||
self.cursorclass = Cursor
|
self.cursorclass = Cursor
|
||||||
self.db = apply(connect, (), kwargs)
|
self.db = apply(connect, (), kwargs)
|
||||||
self.quote_conv[types.StringType] = self.Thing2Literal
|
self.quote_conv[types.StringType] = self.Thing2Literal
|
||||||
self._server_info = self.db.get_server_info()
|
self.db.query('show variables')
|
||||||
i = map(int, split(split(self._server_info, '-')[0],'.'))
|
r = self.db.store_result()
|
||||||
self._server_version = i[0]*10000 + i[1]*100 + i[2]
|
vars = r.fetch_row(0)
|
||||||
|
self._server_vars = {}
|
||||||
|
for k,v in vars: self._server_vars[k] = v
|
||||||
if _threading: self.__lock = _threading.Lock()
|
if _threading: self.__lock = _threading.Lock()
|
||||||
|
|
||||||
if _threading:
|
if _threading:
|
||||||
@ -473,11 +467,13 @@ class Connection:
|
|||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
"""Commit the current transaction."""
|
"""Commit the current transaction."""
|
||||||
if self._server_version > 32315: self.db.query("COMMIT")
|
if self._server_vars.get('have_bdb','NO') == 'YES':
|
||||||
|
self.db.query("COMMIT")
|
||||||
|
|
||||||
def rollback(self):
|
def rollback(self):
|
||||||
"""Rollback the current transaction."""
|
"""Rollback the current transaction."""
|
||||||
if self._server_version > 32315: self.db.query("ROLLBACK")
|
if self._server_vars.get('have_bdb','NO') == 'YES':
|
||||||
|
self.db.query("ROLLBACK")
|
||||||
else: raise NotSupportedError, "Not supported by server"
|
else: raise NotSupportedError, "Not supported by server"
|
||||||
|
|
||||||
def cursor(self, cursorclass=None):
|
def cursor(self, cursorclass=None):
|
||||||
@ -496,10 +492,10 @@ class Connection:
|
|||||||
def get_server_info(self): return self.db.get_server_info()
|
def get_server_info(self): return self.db.get_server_info()
|
||||||
def info(self): return self.db.info()
|
def info(self): return self.db.info()
|
||||||
def kill(self, p): return self.db.kill(p)
|
def kill(self, p): return self.db.kill(p)
|
||||||
def list_dbs(self): return _fetchall(self.db.list_dbs())
|
def list_dbs(self): return self.db.list_dbs().fetch_row(0)
|
||||||
def list_fields(self, table): return _fetchall(self.db.list_fields(table))
|
def list_fields(self, table): return self.db.list_fields(table).fetch_row(0)
|
||||||
def list_processes(self): return _fetchall(self.db.list_processes())
|
def list_processes(self): return self.db.list_processes().fetch_row(0)
|
||||||
def list_tables(self, db): return _fetchall(self.db.list_tables(db))
|
def list_tables(self, db): return self.db.list_tables(db).fetch_row(0)
|
||||||
def field_count(self): return self.db.field_count()
|
def field_count(self): return self.db.field_count()
|
||||||
num_fields = field_count # used prior to MySQL-3.22.24
|
num_fields = field_count # used prior to MySQL-3.22.24
|
||||||
def ping(self): return self.db.ping()
|
def ping(self): return self.db.ping()
|
||||||
|
@ -23,14 +23,21 @@ charge under a license derived from the Python license.
|
|||||||
<p>
|
<p>
|
||||||
<sect2>Linux/UNIX
|
<sect2>Linux/UNIX
|
||||||
<p>
|
<p>
|
||||||
This module is developed on RedHat Linux 5.2 for Intel. It should build without
|
This module is developed on RedHat Linux (currently 7.0)
|
||||||
much trouble on most UNIX-like platforms by using the <tt/build.py/ script.
|
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.)
|
<sect2>Windows (3.11, 95, 98, NT, 2000, CE, BSOD, XYZ, etc.)
|
||||||
<p>
|
<p>
|
||||||
Windows is <em/not/ a supported platform.
|
Windows is <em/not/ a supported platform.
|
||||||
However, the <tt/compile.py/ script
|
However, the <tt/setup.py/ script
|
||||||
reportedly gets the job done.
|
reportedly gets the job done.
|
||||||
Be aware that this is a user-contributed script; the author
|
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.
|
cannot help you with compiling and running under Windows.
|
||||||
<sect1>Python
|
<sect1>Python
|
||||||
<p>
|
<p>
|
||||||
@ -57,19 +64,19 @@ type.
|
|||||||
|
|
||||||
<sect2>MySQL-3.23
|
<sect2>MySQL-3.23
|
||||||
<p>
|
<p>
|
||||||
MySQLdb has only been lightly tested.
|
MySQL-3.23 is presently in gamma (stable prerelease). Several API
|
||||||
MySQL-3.23 is presently in beta (testing) release. Several API
|
|
||||||
additions have been made so far. These will be incorporated into
|
additions have been made so far. These will be incorporated into
|
||||||
MySQLdb as work progresses. As of 3.23.15, transactions are supported
|
MySQLdb as work progresses. As of 3.23.30, transactions are supported
|
||||||
in MySQL using BDB tables. MySQLdb (0.2.2 and up) detects the
|
in MySQL using BDB tables. MySQLdb (0.3.0 and up) detects the
|
||||||
server version upon connection and will issue <tt/COMMIT/ and <tt/ROLLBACK/
|
presence of BDB table support
|
||||||
|
upon connection and will issue <tt/COMMIT/ and <tt/ROLLBACK/
|
||||||
statements when appropriate. Note that MySQL operates in
|
statements when appropriate. Note that MySQL operates in
|
||||||
<tt/AUTOCOMMIT/ mode by default; you will have to issue SQL to
|
<tt/AUTOCOMMIT/ mode by default; you will have to issue SQL to
|
||||||
change this.
|
change this.
|
||||||
|
|
||||||
<sect1>DateTime
|
<sect1>DateTime
|
||||||
<p>If you have the <htmlurl
|
<p>If you have the <htmlurl
|
||||||
url="http://starship.skyport.net/~lemburg/mxDateTime.html"
|
url="http://www.lemburg.com/files/python/mxDateTime.html"
|
||||||
name="DateTime"> module installed (recommended), MySQLdb will use
|
name="DateTime"> module installed (recommended), MySQLdb will use
|
||||||
it for date-related objects. Otherwise, these will be returned to
|
it for date-related objects. Otherwise, these will be returned to
|
||||||
Python as strings. You can also modify the type conversion
|
Python as strings. You can also modify the type conversion
|
||||||
@ -109,14 +116,12 @@ with the same name; use SQL <tt/AS/ to rename fields.
|
|||||||
@ Transactions | <tt>db.commit()</tt> and <tt>db.rollback()</tt>
|
@ Transactions | <tt>db.commit()</tt> and <tt>db.rollback()</tt>
|
||||||
both exist and silently do nothing <ref id="rollback" name="(danger!)">
|
both exist and silently do nothing <ref id="rollback" name="(danger!)">
|
||||||
| <tt>db.commit()</tt> and <tt>db.rollback()</tt> work if the MySQL
|
| <tt>db.commit()</tt> and <tt>db.rollback()</tt> work if the MySQL
|
||||||
client library can perform transactions; otherwise <tt>db.rollback()</tt>
|
server can perform transactions; otherwise <tt>db.rollback()</tt>
|
||||||
is not defined
|
always fails
|
||||||
<caption>Mysqldb to MySQLdb changes</tabular></table>
|
<caption>Mysqldb to MySQLdb changes</tabular></table>
|
||||||
|
|
||||||
<sect1>Zope and ZMySQLDA
|
<sect1>Zope and ZMySQLDA
|
||||||
<p>I'm not distributing a ZMySQLDA patch any more. Somebody else
|
<p>I wrote a <htmlurl url="http://dustman.net/andy/python/ZMySQLDA" name="ZMySQLDA"> for use with MySQLdb.
|
||||||
has written a ZMySQLDA that works with MySQLdb. Find it at
|
|
||||||
<htmlurl url="http://www.zope.org/" name="the Zope home site">.
|
|
||||||
<sect1>Documentation
|
<sect1>Documentation
|
||||||
<p>The web page documentation may be slightly ahead of the latest release
|
<p>The web page documentation may be slightly ahead of the latest release
|
||||||
and may reflect features of the next release.
|
and may reflect features of the next release.
|
||||||
@ -132,7 +137,7 @@ information, see the MySQL documentation. The documentation for this
|
|||||||
module is intentionally weak because you probably should use the
|
module is intentionally weak because you probably should use the
|
||||||
higher-level <ref id="MySQLdb"> module. If you really need it, use the
|
higher-level <ref id="MySQLdb"> module. If you really need it, use the
|
||||||
standard MySQL docs and transliterate as necessary.
|
standard MySQL docs and transliterate as necessary.
|
||||||
<p>Compatibility note: As of 0.2.2, the various fetch_rowXXX() cursor
|
<p>Compatibility note: As of 0.3.0, the various fetch_rowXXX() cursor
|
||||||
methods have been combined into a single fetch_row([n=1[,how=0]])
|
methods have been combined into a single fetch_row([n=1[,how=0]])
|
||||||
method. See the built-in module documentation for more details.
|
method. See the built-in module documentation for more details.
|
||||||
<p>
|
<p>
|
||||||
|
@ -880,12 +880,14 @@ _mysql_row_to_dict_old(
|
|||||||
v = _mysql_field_to_python(c, row[i], length[i]);
|
v = _mysql_field_to_python(c, row[i], length[i]);
|
||||||
if (!v) goto error;
|
if (!v) goto error;
|
||||||
{
|
{
|
||||||
int len;
|
int len=0;
|
||||||
char buf[256];
|
char buf[256]="";
|
||||||
|
if (strlen(fields[i].table)) {
|
||||||
strncpy(buf, fields[i].table, 256);
|
strncpy(buf, fields[i].table, 256);
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
strncat(buf, ".", 256-len);
|
strncat(buf, ".", 256-len);
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
|
}
|
||||||
strncat(buf, fields[i].name, 256-len);
|
strncat(buf, fields[i].name, 256-len);
|
||||||
PyMapping_SetItemString(r, buf, v);
|
PyMapping_SetItemString(r, buf, v);
|
||||||
}
|
}
|
||||||
@ -897,6 +899,45 @@ _mysql_row_to_dict_old(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW);
|
||||||
|
|
||||||
|
int
|
||||||
|
_mysql__fetch_row(
|
||||||
|
_mysql_ResultObject *self,
|
||||||
|
PyObject *r,
|
||||||
|
int skiprows,
|
||||||
|
int maxrows,
|
||||||
|
_PYFUNC *convert_row)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
|
||||||
|
for (i = skiprows; i<(skiprows+maxrows); i++) {
|
||||||
|
PyObject *v;
|
||||||
|
if (!self->use)
|
||||||
|
row = mysql_fetch_row(self->result);
|
||||||
|
else {
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
row = mysql_fetch_row(self->result);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
|
}
|
||||||
|
if (!row && mysql_errno(self->connection)) {
|
||||||
|
_mysql_Exception((_mysql_ConnectionObject *)self->conn);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!row) {
|
||||||
|
if (_PyTuple_Resize(&r, i, 0) == -1) goto error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v = convert_row(self, row);
|
||||||
|
if (!v) goto error;
|
||||||
|
PyTuple_SET_ITEM(r, i, v);
|
||||||
|
}
|
||||||
|
return i-skiprows;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_mysql_ResultObject_fetch_row(
|
_mysql_ResultObject_fetch_row(
|
||||||
_mysql_ResultObject *self,
|
_mysql_ResultObject *self,
|
||||||
@ -912,9 +953,8 @@ _mysql_ResultObject_fetch_row(
|
|||||||
_mysql_row_to_dict_old
|
_mysql_row_to_dict_old
|
||||||
};
|
};
|
||||||
_PYFUNC *convert_row;
|
_PYFUNC *convert_row;
|
||||||
unsigned int maxrows=1, how=0, i;
|
unsigned int maxrows=1, how=0, skiprows=0, rowsadded;
|
||||||
PyObject *r;
|
PyObject *r=NULL;
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist,
|
||||||
&maxrows, &how))
|
&maxrows, &how))
|
||||||
@ -924,28 +964,30 @@ _mysql_ResultObject_fetch_row(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
convert_row = row_converters[how];
|
convert_row = row_converters[how];
|
||||||
|
if (maxrows) {
|
||||||
if (!(r = PyTuple_New(maxrows))) return NULL;
|
if (!(r = PyTuple_New(maxrows))) goto error;
|
||||||
for (i = 0; i<maxrows; i++) {
|
rowsadded = _mysql__fetch_row(self, r, skiprows, maxrows,
|
||||||
PyObject *v;
|
convert_row);
|
||||||
if (!self->use)
|
if (rowsadded == -1) goto error;
|
||||||
row = mysql_fetch_row(self->result);
|
} else {
|
||||||
else {
|
if (self->use) {
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
maxrows = 1000;
|
||||||
row = mysql_fetch_row(self->result);
|
if (!(r = PyTuple_New(maxrows))) goto error;
|
||||||
Py_END_ALLOW_THREADS;
|
while (1) {
|
||||||
|
rowsadded = _mysql__fetch_row(self, r, skiprows,
|
||||||
|
maxrows, convert_row);
|
||||||
|
if (rowsadded == -1) goto error;
|
||||||
|
skiprows += rowsadded;
|
||||||
|
if (rowsadded < maxrows) break;
|
||||||
}
|
}
|
||||||
if (!row && mysql_errno(self->connection)) {
|
} else {
|
||||||
Py_XDECREF(r);
|
/* XXX if overflow, maxrows<0? */
|
||||||
return _mysql_Exception((_mysql_ConnectionObject *)self->conn);
|
maxrows = (int) mysql_num_rows(self->result);
|
||||||
|
if (!(r = PyTuple_New(maxrows))) goto error;
|
||||||
|
rowsadded = _mysql__fetch_row(self, r, 0,
|
||||||
|
maxrows, convert_row);
|
||||||
|
if (rowsadded == -1) goto error;
|
||||||
}
|
}
|
||||||
if (!row) {
|
|
||||||
if (_PyTuple_Resize(&r, i, 0) == -1) goto error;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
v = convert_row(self, row);
|
|
||||||
if (!v) goto error;
|
|
||||||
PyTuple_SET_ITEM(r, i, v);
|
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
error:
|
error:
|
||||||
|
@ -69,7 +69,7 @@ derived from the Python license.
|
|||||||
|
|
||||||
setup (# Distribution meta-data
|
setup (# Distribution meta-data
|
||||||
name = "MySQL-python",
|
name = "MySQL-python",
|
||||||
version = "0.3.0",
|
version = "0.3.2",
|
||||||
description = "An interface to MySQL",
|
description = "An interface to MySQL",
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
author = "Andy Dustman",
|
author = "Andy Dustman",
|
||||||
|
Reference in New Issue
Block a user