Solution declared_attr ; which will be called and added to DeclarativeMeta instances at any time:
Edit : __init__ , automatically provided by declarative , cannot call super() . if you want it, it should be the last one, and the only way to do this is to use the usual mixin.
import datetime from sqlalchemy import Column, DateTime, Integer, String from sqlalchemy.ext.declarative import declared_attr, declarative_base class BaseMixin(object): @declared_attr def last_updated(cls): return Column(DateTime) def __init__(self, last_updated, *args, **kwargs): super(BaseMixin, self).__init__(last_updated=datetime.datetime.now(), *args, **kwargs) print "BaseMixin.__init__" self.last_updated = last_updated ModelBase = declarative_base()
Please note that mixin should be the first!
class User(BaseMixin, ModelBase): """Defines the user but should also have the last_updated inherited from ModelBase""" __tablename__ = 'user' id = Column(Integer, primary_key=True) username = Column(String) def __init__(self, *args, **kwargs): super(User, self).__init__(last_updated=datetime.datetime.now(), *args, **kwargs) print "User.__init__" if __name__ == '__main__': from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create_engine('sqlite:///:memory:', echo=True) ModelBase.metadata.create_all(engine) user = User(username='alice') Session = sessionmaker(engine) session = Session() session.add(user) session.commit()
Nonetheless; Are you sure you want to use __init__ for this first? __init__ not called when objects are returned from requests; and you really want the column to change right now when it has changed. This is already baked in Column() :
from sqlalchemy import func class BaseMixin(object): @declared_attr def created_date(cls): return Column(DateTime, default=func.now()) @declared_attr def modified_date(cls): return Column(DateTime, default=func.now(), onupdate=func.now())
back to using cls= argument
ModelBase = declarative_base(cls=BaseMixin) class User(ModelBase): __tablename__ = 'user' id = Column(Integer, primary_key=True) username = Column(String) if __name__ == '__main__': engine = create_engine('sqlite:///:memory:', echo=True) ModelBase.metadata.create_all(engine) user = User(username='alice') Session = sessionmaker(engine) session = Session() session.add(user) session.commit() session = Session() sameuser = session.query(User).one() sameuser.username = 'bob' session.commit()