declarative_baseのBaseクラスを拡張してみる。

よくmixinで拡張したりなんかする。

e.g. django likeなmodel定義にするmixin

import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class DjangoLikeMixin(object):
    id = sa.Column(sa.Integer, primary_key=True)
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

class Foo(DjangoLikeMixin, Base):
    name = sa.Column(sa.String(255))

engine = sa.create_engine("sqlite://")
engine.echo = True
S = orm.scoped_session(orm.sessionmaker(bind=engine))
Base.metadata.bind = engine
Base.metadata.create_all()

## output
# 2012-03-05 22:47:43,284 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("foo")
# 2012-03-05 22:47:43,284 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:47:43,284 INFO sqlalchemy.engine.base.Engine 
# CREATE TABLE foo (
# 	id INTEGER NOT NULL, 
# 	name VARCHAR(255), 
# 	PRIMARY KEY (id)
# )


# 2012-03-05 22:47:43,300 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:47:43,301 INFO sqlalchemy.engine.base.Engine COMMIT

declarative_baseはclsを引数にとれる。これでBaseクラスを拡張できる。

mixinを使わない例。

import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base

class MyBase(object):
    id = sa.Column(sa.Integer, primary_key=True)
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

Base = declarative_base(cls=MyBase)

class Foo(Base):
    name = sa.Column(sa.String(255))
class Boo(Base):
    name = sa.Column(sa.String(255))

engine = sa.create_engine("sqlite://")
engine.echo = True
S = orm.scoped_session(orm.sessionmaker(bind=engine))
Base.metadata.bind = engine
Base.metadata.create_all()


## output
# 2012-03-05 22:50:12,198 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("boo")
# 2012-03-05 22:50:12,198 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:50:12,198 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("foo")
# 2012-03-05 22:50:12,199 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:50:12,199 INFO sqlalchemy.engine.base.Engine 
# CREATE TABLE boo (
# 	id INTEGER NOT NULL, 
# 	name VARCHAR(255), 
# 	PRIMARY KEY (id)
# )


# 2012-03-05 22:50:12,199 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:50:12,199 INFO sqlalchemy.engine.base.Engine COMMIT
# 2012-03-05 22:50:12,200 INFO sqlalchemy.engine.base.Engine 
# CREATE TABLE foo (
# 	id INTEGER NOT NULL, 
# 	name VARCHAR(255), 
# 	PRIMARY KEY (id)
# )


# 2012-03-05 22:50:12,200 INFO sqlalchemy.engine.base.Engine ()
# 2012-03-05 22:50:12,200 INFO sqlalchemy.engine.base.Engine COMMIT

# Compilation finished at Mon Mar  5 22:50:12