2009/06/19

autoload declarative sqlalchemy

既存 db を Python で読みたい!

SQLAlchemy が正解だと教わったり教わったりで基本はこんな感じらしい
from sqlalchemy import (
create_engine,
MetaData, Table, Column,
Integer, VARCHAR
)
from sqlalchemy.orm import mapper

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
metadata = MetaData()

parent_table = Table('parent_tb', metadata,
Column('id', Integer, primary_key=True),
Column('name', VARCHAR(256)),
)

class Parent(object):
pass

mapper(Parent, parent_table)

Session = sessionmaker(bind=engine)
session = Session()
既存 db から写経で Table 用意して
Class 用意して mapper してあげるの

でも Table とか作るの面倒じゃない? という人には
from sqlalchemy import (
create_engine,
Column,
Integer, VARCHAR
)
from sqlalchemy.ext.declarative import declarative_base

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
Base = declarative_base()

class Parent(Base):
__tablename__ = 'parent_tb'

id = Column(Integer, primary_key=True),
name = Column(VARCHAR(256))

Session = sessionmaker(bind=engine)
session = Session()
__tablename__ とかで色々 Table のこと渡すのね
まぁ、ちょっと楽になったかしら

でも既存の db の Column で登録メンドクサイよ!!という場合
autoload というのを使いなさいと言われ調べたりもした結果
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
Base = declarative_base(engine)

class Parent(Base):
__tablename__ = 'parent_tb'
__table_args__ = {'autoload':True}

class Child(Base):
__tablename__ = 'child_tb'
__table_args__ = {'autoload':True}
parent = relation('Parent', backref='children')

Session = sessionmaker(bind=engine)
session = Session()
こんな感じになりました
いきなり Child できてるけど
declarative_base に engine 食わせてるのは
本当は MetaData に engine か connection が紐付いているべきらしく
class の中で __???__ とかで定義してもいいんだろうけれども
まぁとりあえず動いたし今んとこ engine 1 つだからいいかなと

__table_args__ 使ったけど __autoload__ とかもあるらしいので
詳しいことはちゃんと Table のこと知ってあげないとダメね

何か、一段落して、感動しました
SQLAlchemy 素敵だね!!

0 件のコメント:

コメントを投稿