SQLObject的问题

提到Python的ORM,首先想到的有两个SQLObjectSqlAlchemy,还有Django的ORM,另外,还有Zope的。

前几日和Nicholas又讨论到SQLObject这个东西,就目前Python现有的ORM工具来说,最容易使用还是它了,SqlAlchemy对于懒人、初学者的我来说,还是复杂了点;而Zope相对是个庞然大物,整体的解决方案,小东西往往也不会去用到。

当然SQLObject的问题不在于它使用了ActiveRecord模式,Django的ORM同样也用到了这个模式,因为起初用TurboGears(0.8.9,当时SO的版本可能还没到0.7)做了一个小东西,那个时候便发现了诸多问题,尤其在编码问题上卡住了。这一次正准备对原有的东西增加新的功能,便几乎无法做下去了。

比如业务领域有“角色”这个词,在业务上应当翻译成“Character”。我建立了一个Character类,SO在自动根据代码的Model建立表结构的时候,不会像Rails那样考虑单复数,因此它会尝试建立“character”表,而Character、Char在mysql中都是保留词,而SQLObject甚至都不知道在SQL语句中对其进行转义。为了解决这个问题,我指定SO去建立characters表,接下来的问题就是,SO在寻找Character表相关的外键时,是考虑了characters_id,而对于存在这个外键的表,SO在建表的时候还是使用了character_id这个名字,最终导致了错误。

另外编码又有新问题,Python中使用%格式化操作符时,左边或右边任意一方出现了unicode字符串,最后的结果都会是unicode,而SO也同样没有考虑到,最后导致本已经是unicode的查询字符串,SO还要去再decode一次,最后导致了错误。

所以不推荐大家使用SO,尤其要做复杂产品的时候。

另外,Django的ORM也可以拿出来单独使用,值得研究一下。

Python MySQLdb的重大疑问

最近开发Python,数据库操作一直用的是SQLObject,但有个问题很让我头疼,就是MySQL的数据库的编码问题,主要是MySQL的。
起初我现在我在SQLite上测试开发,并没有出现问题。SQLObject的UnicodeCol工作很正常。而同时起初数据库中并没有任何非ASCII字符(也就是全英文),而后需求变化,增加了欧洲的一些内容,就涉及到latin1编码了,但奇怪的是,只要超出ascii范围(比如中文),即便通过Python将其转化为Unicode或者UTF-8编码的str(使用decode和encode方法),SQLObject在插入的时候就会出错。后来经过反复的检查,是MySQLdb的一个问题,SQLObject会通过获取数据库链接的character_set_name(),取得链接的字符集,然后对查询进行编码以符合这个字符集,但据调试,无论我用什么方法,比如链接的set_character_set()方法、执行“SET NAMES UTF8”这个语句,character_set_name()都总是返回“latin1”,这些可苦了我了,不知道这是不是算一个Bug。