[PEAK] EntityDM._thunk method
Phillip J. Eby
pje at telecommunity.com
Thu Jul 21 00:34:26 EDT 2005
At 01:46 AM 7/21/2005 +0000, Tiago Cogumbreiro wrote:
>Here's a simplified version of the code, in order for it to work:
>
>storage.beginTransaction (self)
>foo = self.FooDM.newItem ()
>bar = self.BarDM.newItem ()
Note that 'newItem()' is deprecated; create objects and 'add()' them instead.
>bar.foo = foo
>self.BarDM.flush () #[1]
>self.FooDM.remove (foo)
>self.FooDM.flush () #[2]
>self.assertEqual (len (self.BarDM), 0)
>self.assertEqual (len (self.FooDM), 0)
>storage.commitTransaction (self)
>
>[1] must be called otherwise the self.FooDM._thunk will be called
When does it get called?
>[2] must be called otherwise len() will get the wrong value because
>the objects - FooDM triggers BarDM into remove 'bar' - will only be
>removed on the end of the transaction.
flush() is an instruction to make the underlying database state match the
in-memory state, so if you are using the _delete_oids mechanism to
implement cascading deletion, it will only take effect at flush() or
commit. If you want to implement a cascading delete that takes effect as
soon as you remove(), you need to override remove() to first call the base
definition of remove, and then do any cascading removes. _delete_oids is
for deleting the identified objects from underlying storage.
In general, if you are implementing a *storage* function, you should be
overriding a method beginning with '_', but if you are implementing a
*behavioral* function (like cascading delete) then you probably should be
overriding a public method.
>My first question is, why do I need to call [1]?
Since I don't know what your DM's do, I can't say. I can only speculate,
as I have above.
>Since my len() is basically returns the value from `self.db ("SELECT
>COUNT(*) FROM Table")`, is there anyway to enforce that flush be
>called and thus it gets a real value?
Well, you could certainly call flush() from len(), and in general if you're
doing queries against an underlying database and not taking into account
the possibly-different in-memory state, you need to flush(). That's what
it's for. The value in flush() being delayed is that it allows
shorter-duration locks in many high-contention database scenarios, and that
it avoids issuing updates on a per-field basis.
More information about the PEAK
mailing list