2015年12月12日土曜日

SQLAlchemy で既存DBを読み込む

SQLAlchemy で手っ取り早く既存DBにアクセスするには、データモデルのクラス定義をする際、__table_args__ の autoload 項目を True に設定すればよい。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

url = (接続するURL情報)
engine = create_engine(url, echo=False)
Base = declarative_base(engine)

class TT_ACTOR(Base):
    __tablename__ = "actor"
    __table_args__ = {"autoload": True}

Session = sessionmaker(bind=engine)
session = Session()

q = session.query(TT_ACTOR)
for actor in q:
    print "%s %s" % (actor.first_name, actor.last_name)
ただし上記の場合、クラス定義が読み込まれる際に対象のデータベースに接続するため、クラス定義前に接続先を決定しておく必要がある。
クラス定義をまとめて外部ファイルからインポートしたい場合などは、import 文(もしくは from 文)以前に Base を構築する処理が必須となる。

クラス定義と接続先情報を疎結合とするため、以下の通り、動的にTable情報を読み込んだのちにクラス定義にマッピングする方法もある。
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, mapper
from sqlalchemy.ext.declarative import declarative_base

class TT_Actor(object):
    pass

url = (接続するURL情報)
engine = create_engine(url, echo=False)
Base = declarative_base(engine)

tables = {name: sqlalchemy.Table(name, Base.metadata, autoload=True,
                                 autoload_with=engine)
          for name in engine.table_names()}
mapper(TT_Actor, tables["actor"])

Session = sessionmaker(bind=engine)
session = Session()
q = session.query(TT_Actor)
for actor in q:
    print "%s %s" % (actor.first_name, actor.last_name)

0 件のコメント:

コメントを投稿