Python で MS Access データファイルを読む

mdbtools, pymdb を使えば Python 上から MS Access のデータファイルが 読めるらしい、と知った。こういうものがネットに転がっているとは 便利な時代になったものである。

Mac だと、MacPorts で glib2 と glib2-dev の切替が巧く行かず、 面倒だったので止めた。

従っていつも通り FreeBSD 上で実行した。10.3 Release。

mdbtools

mdbtools は MDB ファイルを CSV に変換したりするコマンド群とそのライブラリ。 PKG に収録されているので素直にそれをインストールする。

pkg install mdbtools

mdbtools のコマンドで MDB から CSV に変換できるので、 これだけで充分と言えば充分なのだが、やはり直接 Python 上で 扱えた方が便利なので(値にカンマが混じっていたりして クォーテーションされると面倒)、pymdb も入れる。

pymdb

pymdb は mdbtools の Python 用バインディング。PyPi にある。 pip でのインストールは、少なくとも FreeBSD 10.3R 上では不具合が発生した。

  • glibconfig.h が見つからず、ビルド失敗。

    FreeBSD 10 では glibconfig.h は

    /usr/local/lib/glib-2.0/include/glibconfig.h
    

    にあるが、これが pymdb のサーチパスに入っていない。 glibconfig.h 以外の glib 関係のヘッダファイルは

    /usr/local/include/glib-2.0
    

    にあるのに、何故か glibconfig.h だけ別のディレクトリに設置されている。 何故だろう。よく解らない。

    これを解決するだけだったら /usr/local/include とかに glibconfig.h を 無理矢理コピーすれば pip install が通るが、 次の不具合もあるので二度手間になる。

  • libiconv が無視される。

    pymdb の Cコード上で HAVE_ICONV というマクロが検査されるのだが、 pip install では OS 上に libiconv があるのにも関わらず HAVE_ICONV が セットされない。結果として MDB 内の日本語データが文字化けする。

    解決法は、pymdb の setup.py でマクロを定義して、直接ビルドする。

結論として、setup.py に以下の2行を追加する。

define_macros=[("HAVE_ICONV", "1"),],        # 追加
include_dirs=[
    "/usr/local/lib/glib-2.0/include",       # 追加

pymdb の使用感

pymdb の機能は極めて単純で、MDBファイルの中身を

{ table_name: { "headers": [header_list], "data": [[data_row], ...] }, ...}

という構造に変換するだけである。pythonic に利用するにはラッパクラスを作って __getitem__ 等を書くのが良い。例えば、

class MDBRow:
  def __init__(self, header, row, table_name=None, row_idx=None):
    self.headers = header
    self.data = row
    self.table_name = table_name
    self.index = row_idx
    self.extra_data = {}

  def __getitem__(self, col_name):
    try:
      return self.data[self.headers.index(col_name)]
    except ValueError:
      return self.extra_data[col_name]

  def __setitem__(self, col_name, col_data):
    try:
      self.data[self.headers.index(col_name)] = col_data
    except ValueError:
      self.extra_data[col_name] = col_data