diff --git a/mysql/MySQLdb-FAQ.sgml b/mysql/MySQLdb-FAQ.sgml new file mode 100644 index 0000000..ab137f3 --- /dev/null +++ b/mysql/MySQLdb-FAQ.sgml @@ -0,0 +1,178 @@ + +
+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>