SQLAlchemy 0.5から使えるようになったDeclarative APIはマッパーとテーブルとクラスを一度に定義するものらしい。
なのであとはengineをバインドすればよろしくやってくれる。
上の例だと
import datetime
from sqlalchemy import schema, types, orm
metadata = schema.MetaData()
def now():
return datetime.datetime.now()
from sqlalchemy.ext.declarative import declarative_base
# Assign the same metadata object we created earlier.
Base = declarative_base(metadata=metadata)
# We still need the pagetag table because we don't want to explicitly define a
# Pagetag class but still
# need to specify the table in the relation between pages and tags.
pagetag_table = schema.Table('pagetag', metadata,
schema.Column('id', types.Integer,
schema.Sequence('pagetag_seq_id', optional=True), primary_key=True),
schema.Column('pageid', types.Integer, schema.ForeignKey('page.id')),
schema.Column('tagid', types.Integer, schema.ForeignKey('tag.id')),
)
class Page(Base):
__tablename__ = 'page'
id = schema.Column(types.Integer,
schema.Sequence('page_seq_id', optional=True), primary_key=True)
content = schema.Column(types.Text(), nullable=False)
posted = schema.Column(types.DateTime(), default=now)
title = schema.Column(types.Unicode(255), default=u'Untitled Page')
heading = schema.Column(types.Unicode(255))
comments = orm.relation("Comment", backref="page")
tags = orm.relation("Tag", secondary=pagetag_table)
class Comment(Base):
__tablename__ = 'comment'
id = schema.Column(types.Integer,
schema.Sequence('comment_seq_id', optional=True), primary_key=True)
pageid = schema.Column(types.Integer,
schema.ForeignKey('page.id'), nullable=False)
content = schema.Column(types.Text(), default=u'')
name = schema.Column(types.Unicode(255))
email = schema.Column(types.Unicode(255), nullable=False)
created = schema.Column(types.TIMESTAMP(), default=now())
class Tag(Base):
__tablename__ = 'tag'
id = schema.Column(types.Integer,
schema.Sequence('tag_seq_id', optional=True), primary_key=True)
name = schema.Column(types.Unicode(20), nullable=False, unique=True)
page_table = Page.__table__
これをmodel.pyとかしといてpython対話環境で
>>> execfile('model.py')
>>> from sqlalchemy.engine import create_engine
>>> engine = create_engine('sqlite:///test.db')
>>> metadata.bind = engine
>>> metadata.create_all()
とやってengineをバインドすればsqliteのファイルが作られる。metadataのところはテーブルからもアクセスできて
>>> page_table.metadata.bind = engine
>>> page_table.metadata.create_all()
でも同じことができる。
sqlite> .schema
CREATE TABLE comment (
id INTEGER NOT NULL,
pageid INTEGER NOT NULL,
content TEXT,
name VARCHAR(255),
email VARCHAR(255) NOT NULL,
created TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(pageid) REFERENCES page (id)
);
CREATE TABLE page (
id INTEGER NOT NULL,
content TEXT NOT NULL,
posted TIMESTAMP,
title VARCHAR(255),
heading VARCHAR(255),
PRIMARY KEY (id)
);
CREATE TABLE pagetag (
id INTEGER NOT NULL,
pageid INTEGER,
tagid INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(pageid) REFERENCES page (id),
FOREIGN KEY(tagid) REFERENCES tag (id)
);
CREATE TABLE tag (
id INTEGER NOT NULL,
name VARCHAR(20) NOT NULL,
PRIMARY KEY (id),
UNIQUE (name)
);