Running initialization code after creating/loading an object

21 views
Skip to first unread message

Sanjay

unread,
Feb 26, 2007, 7:19:09 AM2/26/07
to sqlalchemy
Hi,

I am not able to code this pattern. I read about it at many places, in
doc, FAQ and at
http://groups.google.co.in/group/sqlalchemy/browse_thread/thread/66d0094c671bd5bc,
but still could not do it. May be my noviceness. Needing help. I tried
somethings like this, but it did not help:

from sqlalchemy import *
from sqlalchemy.ext.assignmapper import assign_mapper
from sqlalchemy.ext.sessioncontext import SessionContext

context = SessionContext(create_session)
session = context.current

metadata = BoundMetaData('sqlite:///satest', echo=False)

# table definitions
person_table = Table('person', metadata,
Column('person_id', Integer, primary_key=True, autoincrement =
True),
Column('first_name', Unicode(30)),
Column('last_name', Unicode(30)))

metadata.drop_all()
metadata.create_all()

class Person(object):

@staticmethod
def Create(first_name, last_name):
p = Person(first_name=first_name, last_name=last_name)
p.CallAfterInitializationOrFetchingFromDatabase()
return p

def CallAfterInitializationOrFetchingFromDatabase(self):
self.full_name = self.first_name + ' ' + self.last_name

class PersonExtension(object):

def create_instance(self, mapper, selectcontext, row, Person):
p = Person()
p.CallAfterInitializationOrFetchingFromDatabas()
return p

assign_mapper(context, Person, person_table,
extension=PersonExtension())

p = Person.Create(first_name="Sanjay", last_name="Patel")
Assert p.full_name == "Sanjay Patel"
p.flush()
del p
session.clear()
p = Person.get_by(person_id=1)
assert p.full_name == "Sanjay Patel"

I think using __new__ might be simpler, but can't guess how exactly
to use it.

thanks
Sanjay

Sanjay

unread,
Feb 28, 2007, 9:23:06 AM2/28/07
to sqlalchemy
Hi All,

Needing help badly. Summarizing my problem: I need to run some
initialization code after an object is retrieved from database. Say I
have a table Person(first_name, last_name), I need that while the
object is fetched, another instance variable named full_name is
assigned as firstname + last_name.

Tried to use MapperExtension by going through the suggestions in some
threads, in the FAQ and the doc, but could not secceed. Also, could
not find out how to use __new__ in this scenario. Surely my
noviceness, either in Python or SQLAlchemy.

Some sample code or specific guidence could help a lot.

thanks
Sanjay

Rick Morrison

unread,
Feb 28, 2007, 11:26:33 AM2/28/07
to sqlal...@googlegroups.com
Hi Sanjay,

Mapper Extension is the way to do this. I use one we call our "compiler" extension, it fires events before database insert, datase update and after database load; you can use these events to modify the object as needed. You can probably hack this into what you need:

class CompilerExtension(MapperExtension):
    """ Allows for "compilation" of sub-items into binary blobs stored on the parent """
    def before_insert(self, mapper, connection, instance):
        instance.oninsert()
        return EXT_PASS
    def before_update(self, mapper, connection, instance):
        instance.onupdate()
        return EXT_PASS
    def populate_instance(self, mapper, selectcontext, row, instance, identitykey, isnew):
        if isnew:
            mapper.populate_instance(selectcontext, instance, row, identitykey, isnew)
            instance.onload()
            return None
        return EXT_PASS

The code for the "onload" is a bit tangled, because SA does not (yet) provide an "after" db load, just a "before". I've asked Mike for another "after" hook (bump, bump), but I think he may have forgotten (bump) about (bump) it (bump...).

Rick

Sanjay

unread,
Mar 2, 2007, 4:53:47 AM3/2/07
to sqlalchemy
Hi Rick,

This was exactly what I needed. Thanks a lot!

Sanjay

(I think I wrote this message yesterday also, which did not appear.
Might have pressed the discard button?!)

Reply all
Reply to author
Forward
0 new messages