Using hash to see if object's attributes have changed

Bryan bryanvick at gmail.com
Fri Dec 11 13:44:54 EST 2009


On Dec 11, 10:17 am, Robert Kern <robert.k... at gmail.com> wrote:
> On 2009-12-11 12:03 PM, Bryan wrote:
>
> > When a user submits a request to update an object in my web app, I
> > make the changes in the DB, along w/ who last updated it and when.  I
> > only want to update the updated/updatedBy columns in the DB if the
> > data has actually changed however.
>
> > I'm thinking of having the object in question be able to return a list
> > of its values that constitute its state.  Then I can take a hash of
> > that list as the object exists in the database before the request, and
> > then on the object that the user has made changes to.  If they are not
> > equal, the user has changed the object.
>
> It *might* work, but probably won't be robust especially as you are relying on
> the string representation. You would be much better off using an ORM, which will
> do all of this for you. This is exactly what they are for.
>
> They usually determine whether attributes have change by instrumentation rather
> than inspection. If you still don't want to use a full ORM, you should at least
> emulate that strategy. Add descriptors to your classes for each attribute you
> want to map to a column. On __set__, they should compare the new value to the
> old, and set a "dirty" flag if the the attribute changes value. Or just
> implement __setattr__ on your classes to do a similar check.
>
> --
> Robert Kern

I am using sqlalchemy, and it does a pretty good job of this.  The
problem is that it considers an object changed whenever an attribute
gets set after the object is loaded, even if the attribute is being
set to the same value.

Another thing I could do is when applying the user's changes to the
object that was loaded from the db, only apply the change if the value
is actually different.  In that case I could use the ORM's isDirty()
test that keeps track of what was set since being loaded.  Then the
object doesn't know anything about its state or isDirty() tests, only
the controller would, which I like as it is less intrusive, but it
also is dependent on a ORM.

Instrumentation would require a bit more work.  I would have to watch
for changes using set/get and __dict__ access.  Also, I would have to
be able to say, "Has this object changed since time x".  Imagine
loading an object from the db.  Depending on the ORM implementation,
it may instantiate an object, then set all its attributes from the DB
row, which would trigger my isDirty instrumentation.  So it would look
dirty even fresh out of the DB w/ no changes.  So I would have to be
able to manually clear the isDirty flag.  Not that any of this is
impossible, just more complex.








More information about the Python-list mailing list