A lazy-committing database object with curry?

Tim Lesher tim at lesher.ws
Mon Jan 19 11:45:45 EST 2004


I'm writing a database helper class that represents records in a SQL
database as objects.  I want to be able to instantiate the objects
(from the database), play with their values locally, then lazily
commit the changes all at once (via an explicit commit call).  Other
than the call to Commit(), I don't want clients of this class to have
to think about the fact that there's a database behind it all--there are
some interesting and non-obvious dependencies on the particular values 
that are committed together, and I want to hide that in the Commit() call.

I'm going to have a number of these, so I wanted to come up with a
solution that's short on glue code and can easily be aggregated into
all the classes that represent record types.  This is what I've come
up with:

# Simple currying class, no kwargs
class curry:
    def __init__(self, fun, *args):
        self.fun = fun
        self.pending = args[:]
    def __call__(self, *args):
        return self.fun(*(self.pending + args))

        
# Simple table:  two columns, "title" and "description"
class SomeRecordType(object):
    def __init__(self, title, description):
        self.__modifications = {}

        # Avoid triggering propset on init
        self.__dict__['title'] = title
        self.__dict__['description'] = description

    def __getValue(name, self):
        try:
            return self.__modifications[name]
        except KeyError:
            return self.__dict__[name]

    def __setValue(name, self, newValue):
        self.modifications[name] = newValue

    name = property(curry(__getValue, 'title'),
                    curry(__setValue, 'title'))
    description = property(curry(__getValue, 'description'),
			   curry(__setValue, 'description'))

    def Commit(self):
        if self.modifications != {}:
            # - snip - Do database commit and clear modifications
            self.__dict__.update(self.modifications)
            self.modifications = {}

So I can do this:

foo = myDb.LookupTitleRecord('some title')
print foo.description    # 'foo'
foo.description = 'bar'  # not updated in the DB yet
print foo.description    # 'bar'
foo.Commit()             # now updated in the DB


Are there any pitfalls to doing this?  Am I being dazzled by the shiny
new toy that is currying?  Is there another simple solution, or a
refinement of this one, that I'm not seeing?

Thanks.

-- 
Tim Lesher
<tim at lesher.ws>



More information about the Python-list mailing list