使用Python的MySQL接口时有过几点经验,不写来自己也经常搞忘。问题主要是由于MySQLdb 或 Python 的版本变化引起。
1. UNICODE的问题。
有些版本的 MySQLdb 不检查所接收的查询的编码,直接将其当作UNICODE处理,以致出错。解决办法是先用isinstance检查输入。
环境:
[xxia@test2 ~]$ uname -r
2.6.9-78.ELsmp
[xxia@test2 ~]$ cat /etc/*release*
cat: /etc/lsb-release.d: Is a directory
CentOS release 4.7 (Final)
[xxia@test2 ~]$ python
Python 2.3.4 (#1, Jul 25 2008, 14:23:21)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
im>>> import MySQLdb
>>> MySQLdb.__version__
'1.2.1_p2'
解决方案是修改MySQLdb:
[xxia@test2 ~]$ diff /usr/lib64/python2.3/site-packages/MySQLdb/cursors_orig.py /usr/lib64/python2.3/site-packages/MySQLdb/cursors.py
146c146
< query = query.encode(charset)
---
> if isinstance(query, unicode): query = query.encode(charset)
2. 时间的类型问题。
老一些的版本从数据库中返回的时间是一个 mxDateTime (mx.DateTime)对象,近一些的版本则返回 datetime.datetime对象,因此也应作检查:
if hasattr(r_time, 'timetuple'):
time_struct = r_time.timetuple()
else:
time_struct = r_time.tuple()
3. 字符串的类型。
对于数据库类型为 char 或 varchar 类型的字符型数据,早期的MySQLdb返回字符串,后来一些版本返回 array.array 类型,近一些的版本返回 set 类型,因此也需要检查。如能在程序中根据 MySQLdb 的版本来调整是最好的,不过我不愿调查MySQLdb具体各版本的情况,采取一个懒办法:
from array import array
from sets import Set
tp = type(rlt)
if tp is array:
rlt = rlt.tostring()
elif tp is Set:
rlt = rlt.pop()