import sqlalchemy as sa
from sqlalchemy import orm
import traceback

metadata = sa.MetaData()
metadata.bind = 'sqlite:///:memory:'

session = orm.sessionmaker()

users_table = sa.Table(
    'users', metadata,
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('name', sa.String),
    sa.Column('date_created', sa.DateTime,
              default=sa.func.current_timestamp()),
    )

metadata.create_all()

class User(object):
    pass

class AuditExtension(orm.MapperExtension):
    def get_pk(self, mapper, instance):
        return ', '.join(map(str, mapper.primary_key_from_instance(instance)))
                         
    def after_insert(self, mapper, connection, instance):
        print "INSERT %s(%s)" % (type(instance).__name__,
                                 self.get_pk(mapper, instance))
        for prop in mapper.iterate_properties:
            try:
                print "  %s = %r" % (prop.key, getattr(instance, prop.key))
            except Exception, e:
                print "#" * 70
                print "Exception while accessing %s" % prop.key
                traceback.print_exc()
                print "#" * 70

    def after_update(self, mapper, connection, instance):
        print "UPDATE %s(%s)" % (type(instance).__name__,
                                 self.get_pk(mapper, instance))
        for prop in mapper.iterate_properties:
            history = getattr(type(instance), prop.key).get_history(instance)
            if history.is_modified():
                print '   %s: %r -> %r' % (prop.key,
                                           history.deleted_items(),
                                           history.added_items())



orm.mapper(User, users_table, extension=AuditExtension())

sess = session()

u = User()
u.name = 'Tom'

sess.save(u)

sess.flush()

print "Getting date_created"
print u.date_created

u.name = 'Dick'
sess.flush()
