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

Blogを作る(2)データベースの設定

Pylons

 前回の続きです。

データベースの設定

 続いて、データベースの設定を行います。まず、BlogTutorial/development.iniを編集し、データベースの接続先を設定します。
 development.iniを開くと、コメントアウトされているsqlalchemy.dburiという設定があるので、このコメントアウトを外し、SQLAlchemyのDSNに従って接続先を設定します。


 MySQLの場合、次のようになります。MySQLdbのバージョンによってはcharsetオプションが使えませんが、使用できる場合はこのオプションを設定することをお勧めします。

sqlalchemy.dburi = mysql://user:password@localhost/dbname?charset=utf8
sqlalchemy.echo = True


 SQLiteの場合、%(here)sプレイスホルダーを使うと、プロジェクトのホームディレクトリを指定できるので便利です。

sqlalchemy.dburi = sqlite:///%(here)s/blog.db
sqlalchemy.convert_unicode = True
sqlalchemy.echo = True


 アプリケーション内部では、一貫してユニコード文字列を扱うことを保障するために、sqlalchemyのconvert_unicodeオプションを設定しました。また、SQLAlchemyのクエリやクエリ発行のタイミングを理解し易くするために、デバッグ用のオプションechoを設定しています。


 ここから先は、SQLiteを使用してることを前提に進めていきます。

モデルを定義する

 モデルクラスは、blogtutorial/modelsモジュールに定義します。後で手を入れるつもりですが、まずはBlogのエントリに対応するモデル"Post"のみを定義します。

# -*- coding: utf-8 -*-
from sqlalchemy import *
from sqlalchemy.orm import *
from pylons.database import session_context

__all__ = ['metadata', 'Post']

class Post(object):
    def __init__(self, title=None, content=None, **kwds):
        self.id = None
        self.title = title or u''
        self.content = content or u''
        self.posted_at = None
        self.modified_at = None

metadata = DynamicMetaData()
    
post_table = Table('blog_post', metadata,
                   Column('id',
                          Integer,
                          primary_key=True),
                   Column('title',
                          String),
                   Column('content',
                          String),
                   Column('posted_at',
                          DateTime,
                          default=func.current_timestamp()),
                   Column('modified_at',
                          DateTime,
                          default=func.current_timestamp(),
                          onupdate=func.current_timestamp())
                   )

mapper(Post, post_table)


 注意すべきは、2行目のように"from sqlalchemy import *"として、sqlalchemyモジュールのシンボルをすべて、このblogtutorial.modelsモジュールレベルにインポートしないといけないという点です。"import sqlalchemy as sa"のように、別名でインポートした場合は、データベースに接続するために、自分で初期化用のコードを足さなくてはなりません。
 また、3行目の"from sqlalchemy.orm import *"は、SQLAlchemyの現在のバージョン(0.3.X系)では必要ありませんが、将来のバージョンで必要になることが予告されているので、ここでもそれに従うことにします。

アプリケーションの初期化

 アプリケーション導入時の初期化コードは、websetup.pyに記述します。プロジェクトを作成時に作られたwebsetup.pyは、次のようになっていると思います。

import paste.deploy
from pylons.database import create_engine

def setup_config(command, filename, section, vars):
    """
    Place any commands to setup blogtutorial here.
    """
    conf = paste.deploy.appconfig('config:' + filename)
    paste.deploy.CONFIG.push_process_config({'app_conf':conf.local_conf,
                                             'global_conf':conf.global_conf})

    pass


 pass以降に、必要な初期化コードを書いていきます。データベースにテーブルを作成し、テスト用の行を挿入するコードを追加しました。

    from sqlalchemy import create_session
    engine = create_engine(conf['sqlalchemy.dburi'])
    metadata.connect(engine)

    # テーブルを作成
    metadata.create_all()

    # テスト用の行を作成
    session = create_session(engine)
    session.save(Post(title=u'テスト',
                      content=u'テスト'))
    # ここでコミット
    session.flush()


 最終的に、websetup.pyは次のようになりました。

# -*- coding: utf-8 -*-
import paste.deploy
from pylons.database import create_engine

from sqlalchemy import create_session
from blogtutorial.models import *

def setup_config(command, filename, section, vars):
    """
    Place any commands to setup blogtutorial here.
    """
    conf = paste.deploy.appconfig('config:' + filename)
    paste.deploy.CONFIG.push_process_config({'app_conf':conf.local_conf,
                                             'global_conf':conf.global_conf})
    
    engine = create_engine(conf['sqlalchemy.dburi'])
    metadata.connect(engine)
    metadata.create_all()

    session = create_session(engine)
    session.save(Post(title=u'テスト',
                      content=u'テスト'))
    session.flush()


 この初期化処理を実行するには、コマンドラインからpasterを使って、

$ paster setup-app development.ini

を実行します。


 これで、上のdevelopment.iniで設定したように、プロジェクトディレクトリ/blog.dbというSQLiteデータベースファイルが作られ、必要なテーブルも作成されました。


 つづく。