mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-16 12:27:03 +08:00
Attempt to save my sanity.
This commit is contained in:
178
mysql/MySQLdb-FAQ.sgml
Normal file
178
mysql/MySQLdb-FAQ.sgml
Normal file
@ -0,0 +1,178 @@
|
||||
<!doctype linuxdoc system>
|
||||
<article>
|
||||
<title>MySQLdb FAQ
|
||||
<author>Andy Dustman
|
||||
<date>$Id$
|
||||
<sect>Compiling <tt/_mysqlmodule.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/_mysqlmodule.so/ against these, but these are not on your loader path
|
||||
when you start Python.
|
||||
You have two basic options:
|
||||
<p>
|
||||
<enum>
|
||||
<item>
|
||||
Modify the compiler flags in Setup so that it links against the static
|
||||
library. Probably <tt/-static/ will do this for gcc/egcs; YMMV for
|
||||
other C compilers.
|
||||
<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: ./_mysqlmodule.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 from your vendor or python.org.
|
||||
|
||||
<sect1>./_mysqlmodule.c:33: mysql.h: No such file or directory
|
||||
|
||||
<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
|
||||
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
|
||||
libraries (see above), you can install <tt/_mysqlmodule.so/ on a system
|
||||
that does not have the MySQL client libraries (<tt/libmysqlclient/).
|
||||
|
||||
<sect1>I'm using Windows...
|
||||
<P>Say no more.
|
||||
<P>There is a <tt/compile.py/ script which supposedly gets the job done
|
||||
for Windows, but I can't test it.
|
||||
</sect1>
|
||||
<sect>
|
||||
Trouble with ZMySQLDA
|
||||
<p>There are a few tricks to getting Zope's ZMySQLDA to work with
|
||||
<tt/_mysql/. But it ain't that hard, really.
|
||||
Also see the
|
||||
<htmlurl url="http://www.zope.org/Members/alanpog/zmysqlda_steps"
|
||||
name="ZMySQLDA HOWTO">.
|
||||
<sect1>Building ZMySQLDA
|
||||
<p>
|
||||
The basic steps are:
|
||||
<enum>
|
||||
<item>Install MySQLdb first, so that it's on your <tt/PYTHONPATH/
|
||||
and Zope can find it.
|
||||
<item>Untar the ZMySQLDA tarball (available from
|
||||
<htmlurl url="http://www.zope.org/Members/MikeP/ZMySQLDA"
|
||||
name="zope.org">).
|
||||
<item>Patch it with the ZMySQLDA.patch included with the MySQLdb
|
||||
distribution. In the directory that you did the untar,
|
||||
<code>
|
||||
patch -p1 </path/to/ZMySQLDA.patch
|
||||
</code>
|
||||
<item>If you do a make, which is what the ZMySQLDA instructions
|
||||
tell you, it will try to compile the older
|
||||
MySQLmodule, which you don't need. Ignore stuff like:
|
||||
<code>
|
||||
./MySQLmodule.c: In function `pythonify_row':
|
||||
./MySQLmodule.c:238: warning: assignment from incompatible pointer type
|
||||
./MySQLmodule.c: In function `pythonify_res_fields':
|
||||
./MySQLmodule.c:384: invalid lvalue in unary `&'
|
||||
./MySQLmodule.c: In function `STH_fetchdict':
|
||||
./MySQLmodule.c:1125: invalid lvalue in unary `&'
|
||||
./MySQLmodule.c:1147: invalid lvalue in unary `&'
|
||||
make: *** [MySQLmodule.o] Error 1
|
||||
</code>
|
||||
MySQLmodule.c doesn't compile against
|
||||
MySQL-3.22 without patches. Which is why MySQLdb exists...
|
||||
<item>Restart Zope. You should have a ZMySQLDA Product in the
|
||||
Control Panel.
|
||||
</enum>
|
||||
<sect1>How do I use it?
|
||||
<P>I'm not the best person to ask. There are two main steps to getting
|
||||
started.
|
||||
<enum>
|
||||
<item>Create a ZMySQLDA Connection object somewhere.
|
||||
<item>The connect string syntax is "database@host user password".
|
||||
If the database is on the same host as the Zope server, you can leave
|
||||
out @host. You might be able to leave off user and password as well,
|
||||
depending on your GRANT tables. Whether or not this is a good idea is
|
||||
another question.
|
||||
<item>You're on your own. I recommend reading the
|
||||
<htmlurl url="http://www.zope.org/Documentation/Guides/ZSQL-HTML/ZSQL.html"
|
||||
name="Z SQL Method's User Guide"> and maybe
|
||||
<htmlurl url="http://www.zope.org/SiteIndex/search?text_content=sql"
|
||||
name="searching the Zope website for SQL">.
|
||||
</enum>
|
||||
<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://starship.python.net/crew/adustman/MySQLdb.html"
|
||||
name="MySQLdb documentation">.
|
||||
<sect1>What do I do if I am completely clueless?
|
||||
<p>Get a clue. Clues have been provided in the <tt/examples/ directory
|
||||
of the MySQLdb distribution.
|
||||
<sect1>No, I mean <em/really/ clueless!
|
||||
<p>Okay, it goes something like this:
|
||||
<enum>
|
||||
<item>
|
||||
Import MySQLdb.
|
||||
<item>
|
||||
Create a Connection object.
|
||||
<item>
|
||||
Create a Cursor object.
|
||||
<item>
|
||||
Execute your query on the Cursor object.
|
||||
<item>
|
||||
If your query returns rows, you can use the Cursor object to fetch them.
|
||||
<item>
|
||||
Rinse, lather, repeat.
|
||||
</enum>
|
||||
Example:
|
||||
<code>
|
||||
import MySQLdb
|
||||
db = MySQLdb.connect(db='mydb',user='myuser',passwd='mypasswd')
|
||||
c = db.cursor()
|
||||
c.execute(myquery)
|
||||
results = c.fetchall()
|
||||
</code>
|
||||
<sect1>But MySQL doesn't have cursors!
|
||||
<p>True enough. MySQLdb fakes it, though, because the spec requires it.
|
||||
<sect1>cursor.rollback() is missing!
|
||||
<p>MySQL doesn't do transactions. <tt/cursor.rollback()/ is supposed to
|
||||
roll back (cancel) the current transaction. If you really need to do
|
||||
this, then you definitely want <tt/cursor.rollback()/ to fail, because
|
||||
it can't do what you want it to do.
|
||||
<p>OTOH, <tt/cursor.commit()/, which attempts to commit the transaction
|
||||
to the database, <em/does/ exist and always succeeds, because MySQL
|
||||
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?
|
||||
<P>Short answer: Don't, if you can avoid it. Your program will not
|
||||
be portable to other databases.
|
||||
<P>Long answer: MySQLdb exports all symbols from _mysql. There are only
|
||||
a couple MySQL functions available this way, though. The Connection object
|
||||
does wrap nearly all of the various MySQL calls that use a <tt/MYSQL/
|
||||
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
|
||||
<tt/db.select_db(newdb)/ where <tt/db/ is your Connection object.
|
||||
<sect1>I still wanna use _mysql directly.
|
||||
<p>Well, it <tt/may/ be appropriate in some cirumstances. The patched
|
||||
ZMySQLDA does this, because MySQLdb does a lot of type conversion that
|
||||
isn't necessary for Zope's purposes.
|
||||
<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.
|
||||
</enum>
|
||||
</article>
|
Reference in New Issue
Block a user