2010/11/17

SQLAlchemy で collate が utf8_bin なカラムだとユニコード文字列で取得出来ない

某システムで検索の仕様変えることになって(厳密にはいろいろ違うけど)、大文字小文字の区別付けるために検索対象のカラムの collate を utf8_general_ci から utf8_bin に変更した。

ALTER TABLE `hoge` MODIFY `col` VARCHAR(255) NOT NULL DEFAULT '' CHARACTER SET utf8 COLLATE utf8_bin

検索は PHP で書いてて、テストも問題無かったからデプロイしたんだけど、このテーブルを Python で書いたクローラも参照してたから、ちょっと問題が出た。

from sqlalchemy import *
from sqlalchemy.sql import select

engine = create_engine('mysql://localhost/sandbox', echo=False, encoding='utf-8', convert_unicode=True)
conn = engine.connect()
metadata = MetaData(bind=engine)
tbl1 = Table('table1', metadata, autoload=True)

for row in conn.execute(select([tbl1])):
    print row # Unicode文字列になっていない

ORM 使わないで書いてたやつなんだけど、取得した結果の文字カラムがユニコード文字列になってなくて、お馴染の UnicodeDecodeError でクローラが落ちる…。

そもそもの書き方が悪い、っていうのがあるんだけど、一旦それは置いといて(というかすぐ直した)原因は何なのかってのを調べてみる。

ローカルの環境は MySQL 5.1.51 + SQLAlchemy 0.6.1 で、上記のコードを試すと結果はユニコード文字列になってる。

あれ、ってことで本番環境確認すると MySQL 5.0.91 + SQLAlchemy 0.6.1…なんだけど、DB サーバは別にあってそっちは MySQL 5.1.51。 SQLAlchemy のバージョン上げれば解決、だと思ったんだけど、問題解決にはならず結果は同じ…。

あんまり検証してないけど、とりあえずこういうことらしい。SQLAlchemy がその辺うまいこと処理してくれるものだと思ってたんだけど、どうなんだろう…。

それにしても余裕が無い…。

blog comments powered by Disqus