読者です 読者をやめる 読者になる 読者になる

Elixirちょうだい!

Python SQLAlchemy

 Elixirは、SQLAlchemyをバックエンドにして、SQLObjectやdjango.dbのようなアクティブ・レコード・パターンを実装したORMライブラリです。


Elixir
http://elixir.ematia.de/


 インストールはeasy_installで。

$ easy_install Elixir


 練習に、簡単なブログの定義を書いてみました。1つのエントリに対して、1つのカテゴリが対応しています。

# -*- coding: utf-8 -*-
# blog.py
from elixir import *

# SqliteオンメモリDBを開く
metadata.connect('sqlite:///')

# Debug用のログを有効にする
metadata.engine.echo = True

class Entry(Entity):
    with_fields(
        title = Field(Unicode(100)),
        text  = Field(Unicode()),
        pub_date = Field(DateTime())
    )

    belongs_to('category', of_kind='Category')
    
    def __repr__(self):
        return '<Entry "%s">' % self.title

class Category(Entity):
    with_fields(
        name = Field(Unicode(20))
    )
    
    has_many('entries', of_kind='Entry')
    
    def __repr__(self):
        return '<Category "%s">' % self.name

if __name__ == '__main__':
    # DBにテーブルを作る
    create_all()


 SQLAlchemyのMapperの場合は、Tableオブジェクトと、それに対応付けられるオブジェクトを定義する必要がありましたが、Elixirでは、django.dbと同じように、モデルクラスを定義するだけで済みます。あらかじめDBにテーブルを作成していない場合は、このアプローチの方が楽ですね。


 新しく行を挿入するには、モデルクラスを作って、objectstore.flush()を呼び出します。

from datetime import datetime
from blog import *

entry = Entry(title=u'テスト',
              text=u'spam spam spam spam',
              pub_date=datetime.now())
py = Category(name=u'Python')
py.entries.append(entry)

# ここでコミット
objectstore.flush()


 Entry.table, Category.tableでSQLAlchemyのTableオブジェクトにもアクセスできるので、SQLAlchemyで可能な操作をすべて実行することができます。

from sqlalchemy import and_
from blog import *

# カテゴリが"Python"のエントリを探す
# もっと簡単な書き方がありそうですが・・・
Entry.select(from_obj=[
    Entry.table.join(Category.table,
        and_(Entry.table.c.category_id==Category.table.c.id,
             Category.table.c.name=="Python")
        )
    ])


 ElixirをTurboGearsで使う例もあるので、もっとTurboGears派の人たちから注目されてもいいと思うのですが、まだ開発途上だからということでしょうか?