[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.
>