[Zope] when to opt for a backend DB over ZClasses?

Steve Spicklemire steve@spvi.com
Tue, 4 Sep 2001 04:21:27 -0500


Hi Darran,

	I'm cc-ing the list so other folks who look at the example might 
use the help.

On Tuesday, September 4, 2001, at 03:25 AM, Darran Edmundson wrote:

>
> Hi Steve,
>
> Thanks for the ZPatterns tip.  I've downloaded the
> attendance example and, while I don't understand how
> it works, I like the end result ;-)  I've tried
> unsuccessfully to get my head around ZPatterns on a
> number of occassions, inevitably falling back on
> a more familiar solution.
>

Well.. it's not so hard once you get the hang of it. ;-)

> Any tips on coming to grips with this paradigm in
> the context of your example?

I'll give it a whirl! Basically, each object type gets a Specialist to 
manage instances of that object type (e.g., objects of type "Attendee" 
are managed by the "Attendees" Specialist). The Specialist delegates all 
responsibility for the actual storage of it's objects to a "Rack" that 
it contains. The objects themselves (e.g., Attendees) are sub-classed 
from ZPatterns:DataSkin, and are designed to further delegate all 
responsibility for the actual storage of their *attributes* to the Rack 
in which they are stored. When an object is used in an application, and 
the application needs a certain attribute (e.g., name) the object checks 
with it's rack for an "attribute provider" for that attribute. If it 
finds one it uses it to return the attribute to the object that needed 
it. If it doesn't find one, it returns NameError.

>  Where are your attendance
> zclasses being created?

The ZClasses live in the /Control_Panel/Products/AttendanceProducts 
folders. The ZClass *instances* are created when someone calls any of 
the applications' Specialists "newItem(id=...)" methods. newItem only 
has one argument, "id". When  newItem is called, an instance of the 
corresponding object is created and returned to the caller. This action 
also fires any "WHEN OBJECT CREATED" triggers in the Rack of the 
Specialist (since the Specialist just forwards newItem to it's rack)

>  And are they persistant on
> the server across multiple requests?

Yes. they are persistent until someone deletes them! DataSkins have a 
manage_delete() method that also fire any "WHEN OBJECT DELETED" triggers 
in the Rack of the corresponding Specialist. The ideas of Triggers, and 
attribute providers are really important. Here is the SkinScript from a 
typical Rack (found in the Data PlugIns tab) that uses SQL:


The first three are "Triggers", actions that occur when stuff happens to 
the object:

WHEN OBJECT ADDED CALL
	insertSQL(mergedsectionID=self.id, targetCourseID = 
self.targetCourseID, section = self.section)

WHEN OBJECT DELETED CALL deleteSQL(mergedsectionID=self.id)

WHEN OBJECT CHANGED STORE
	targetCourseID, section USING
	updateSQL( mergedsectionID=self.id, targetCourseID = 
self.targetCourseID, section = self.section)

Where insertSQL, updateSQL, and deleteSQL are ZSQLMethods that perform 
those actions.

The fourth is an attribute provider, (i.e., how to I get the attributes 
of one of these
objects when they are accessed?):

WITH QUERY selectSQL(mergedsectionID=self.id) COMPUTE
	mergedsectionID, targetCourseID, section


>  I'd love to
> have someone explain this to me in Socratic fashion ;-)

Sounds like a novel approach. ;-) The idea is that the application uses 
a really simple API:

newItem() to create new objects
getItem() it get existing objects

and the object's own manage_delete() method to destroy objects.

In my own applications I use a method called 
getItemIds(conditions = {} ) returns a list of ids that satisfy a set of 
conditions passed as a dictionary. This method can call a "Select ... " 
query or query a catalog depending on how the objects are *really* 
stored. But this keeps all the data dependent stuff contained in a small 
number of places: The Rack, getItemsIds, and then the actual queries, db 
adaptor *or* a Catalog (*or* LDAP, *or* whatever else.. ).

The thing I love about ZPatterns is the degree to which you can write an 
application *whithout* worrying about the data, but focus on the logic 
*first*. Most of my apps are generated first using ZODB, then, if 
necessary, converted to SQL using the "ZClass lever" thingy included in 
the example. It's nice since it generates all the SQL and skinscript for 
you based on the propertysheets in the ZClasses that represent the 
"definition" of your data. Of courses, the one that comes with the 
example is set up for gadfly, but "salt to taste" and all that.

thanks for the questions!
-steve

> Cheers,
> Darran.
>