技術情報棚卸し(平日限定)

todoa2cの技術情報棚卸しです。平日限定ってことはアレだ。言わせんな恥ずかしい。

ちっちゃいWeb APIをPython 3.3に移行する

Python 2.6時代

2012年夏頃、ちょっとした自然言語処理用Web APIを作ることになったとき、 実現方法を色々探した結果、Natural Language Toolkit (NLTK)に辿り着き、 それからPythonを触るようになりました。

周囲には誰もPythonを使ったことのある人がいなかったので、 独学でPythonやNLTKを学んだ結果、以下の様な構成になりました。

  • Python 2.6 (EC2環境にデフォルトで入っていたものをそのまま利用…)
  • web.py (軽量Webアプリケーションフレームワーク)
  • NLTK (自然言語処理モジュール)
  • SQLAlchemy (ORM)
  • MySQL-Python (MySQLドライバ)

この構成はぼちぼちうまく動いていたのですが、文字列マルチバイト対応の面倒臭さや、 Python 2.6.9が2.6系最後のリリース とうことを知ってから、モジュールの構成を変えることを検討し始めたわけです。

Python 3.3時代

まず、無難に2.7系に行くか3.x系に行くかを検討しましたが、 文字列マルチバイト対応の面倒臭さから逃げたかったため、 Python 3.xを使うこと自体はあっさり決まりました。

3.xを使うことを決めた次に、ライブラリがそのまま使えるかを調査しました。 2系と3系の違い – Python入門から応用までの学習サイトにも書かれているように、 Python 2.x系から3.x系では互換性が失われる変更が多数入ったので、 2.x系で使えていたライブラリが3.x系で使えない可能性があるのです。

調査したところ、調査時点(2014年1月時点)ではこのような対応状況でした。 主要なライブラリが1コしか対応していない…なかなかの難局です。

  • web.py: 3.x系未対応(対応するためのPull Requestは出ているがここ数ヶ月動きなし)
  • NLTK: 3.x系未対応(ただしNLTK 3.0 Alpha Releasesはある)
  • SQLAlchemy: 対応済み
  • MySQL-Python: 3.x系未対応

結局それなりの時間を費やして調査比較検討した結果、下記のような環境に落ち着きました。

  • Python 2.6 → Python 3.3
  • web.py → Flask (web.py同様の軽量さに好感)
  • NLTK → scikit-learn (実際やっていたのはテキスト分類なので、機械学習ライブラリに移行)
  • SQLAlchemy → そのままSQLAlchemy
  • MySQL-Python → PyMySQL (Python 3のMySQLドライバ事情が参考になります)

これにより、Web層とロジックの書き換えこそ必要になってしまいましたが、 そもそも規模が小さいWeb APIなので、割と簡単に置き換えができました。

MySQL-PythonからPyMySQLへの移行は、接続先のURLのschema部分をmysql://からmysql+pymysql://に 変更するだけでOK。

移行してみて

Python 2.x系から3.x系に移行するには、やはり今まで使えたライブラリが使えない、 という問題が出てきます。 ですが、何かしら代替となりそうなライブラリはあるみたいですので、 調査や移行に時間こそかかりますが、Python 3.xに移行できるのかなぁと思った次第です。

また、本件では触れていませんが、Python 2.x系だけでしか動かなかったライブラリを 2.x系、3.x系両方で動かす対応を経験したのも大きいかもしれません。

代替ライブラリがない場合、最悪、フォークして自分でPython 3.x対応する、という手段もある、 と思うようになったことも、Python 3.xに移行するきっかけになったと思っています。

ちょっと話はそれましたが、まとめ。 規模が大きいプロジェクトの場合は移行が難しいかもしれませんが、 小規模なプロジェクトの場合であれば、移行は意外と何とかなるんじゃないかな、 というのが今回の感想でした。

Comments