ラベル SQLAlchemy の投稿を表示しています。 すべての投稿を表示
ラベル SQLAlchemy の投稿を表示しています。 すべての投稿を表示

2016年4月25日月曜日

SQLAlchemy で既存テーブルに INDEX を作成する方法

既に存在しているテーブルに対して INDEX を生成するには、sqlalchemy.Index クラスを用いる。
Index("インデックス名", "カラム名_1", "カラム名_2", ・・・) として、生成されるオブジェクトのメソッド create により INDEX を作成する。

なお、以下の例では sakila データベースの language テーブルに対して、INDEX を生成している。
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Index

url = <対象データベースへの接続用URL>
engine = create_engine(url, echo=False)
Base = declarative_base(engine)


class TT_LANGUAGE(Base):
    __tablename__ = "language"
    __table_args__ = {"autoload": True}


if __name__ == '__main__':

    i = Index("IX01_LANGUAGE", TT_LANGUAGE.__table__.c.name.desc())
    i.create(engine)

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)

2013年7月27日土曜日

SQLAlchemy でテーブルを作成する。

テーブルを作成する場合、当該テーブルが既に存在している場合は削除した上で作成する、といった分岐処理が必要になる。 SQLAlchemy は、drop および create 関数に checkfirst 属性を有しており、エラーの場合は、当該処理を実行しないようにすることができる。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String

Base = declarative_base()

class TT_USER(Base):
    __tablename__ = "TT_USER"

    id = Column(Integer, primary_key = True)
    name = Column(String(20))

if __name__ == '__main__':
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker

    mysql_db = create_engine(対象データベースへのURL)
    TT_USER.__table__.drop(mysql_db. checkfirst = True)
    TT_USER.__table__.create(mysql_db)

上記の場合、drop 時にテーブルが存在していない場合は、drop を実行しない。