The PEAK Developers' Center   PeakDatabaseApplications UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View
The following 304 words could not be found in the dictionary of 50 words (including 50 LocalSpellingWords) and are highlighted below:
Application   As   Because   Binding   Changing   Classes   Component   Connection   First   Here   In   Intro   Introduction   It   Lite   Make   Naming   Note   Obtain   On   Peak   Python   Root   So   Steps   Such   Table   The   This   Tightly   To   Transaction   Using   We   What   When   With   Without   Work   Worker   ability   able   about   access   accomplish   achieved   against   all   already   also   always   an   and   another   api   app   application   applications   approach   are   as   aspects   at   attribute   attributes   automatic   automatically   base   based   be   because   begin   bind   binding   bindings   bit   briefly   brittle   build   building   by   calls   can   capable   certain   changes   class   classes   combination   commit   component   components   config   connection   continued   coupled   coupling   create   creating   creation   database   db   def   defining   definition   demonstrates   dependencies   dependent   description   different   discuss   do   done   draft   drawback   each   easily   easy   either   embeds   ensuring   error   every   example   excellent   exists   extremely   file   find   first   flexible   for   forces   former   forms   found   from   great   hand   have   help   hierarchy   highly   however   if   import   in   incomplete   instance   instances   instantiate   instantiates   inter   interface   interfaces   is   it   its   kind   know   known   large   larger   less   level   like   line   lines   ll   lookup   looser   main   make   means   mechanism   missed   module   most   must   name   naming   need   needed   needs   new   not   number   object   objects   of   offer   often   on   once   one   only   opens   or   org   other   package   packages   page   parameter   parent   part   pass   peak   platform   please   powerful   print   prints   programmer   prone   properties   provide   provides   publishing   query   quick   quickly   quite   relatively   requires   rest   result   results   reusable   reused   root   row   run   runs   see   select   self   separate   server   service   setting   several   shared   should   simply   single   singleton   singletons   small   software   some   sort   specifying   sqlite   starting   still   storage   structure   subclasses   subclassing   such   supplied   table   taking   task   technique   tends   test   that   the   then   there   these   this   through   throughout   tightly   to   top   tutorial   type   typically   use   useful   using   usually   utilities   values   variables   various   via   want   way   we   what   which   will   with   within   worker   working   would   wouldn   you  

Clear message


1 Introduction

Note: this page is an incomplete draft; please see IntroToPeak for a tutorial.

PEAK is an excellent platform for building Python database applications. Using a combination of several PEAK packages one can build powerful and flexible database applications quickly and easily.

2 First Steps: Binding and Naming

We should first discuss briefly the PEAK packages we'll be working with, starting with peak.binding and peak.naming.

Peak's binding package provides powerful utilities for building component-based applications. This typically means that you create a top-level application class of some sort which instantiates the various component objects needed to accomplish the task at hand. With peak.binding these "component objects" will be able to find each other, most often by defining properties that "bind to" other objects in the hierarchy. Here's a quick example:

    1 from peak.api import binding, storage
    2 
    3 class Worker(binding.Component):
    4     db = binding.Obtain(storage.ISQLConnection)
    5     def doWork(self):
    6         for row in self.db('select name, description from aTable'):
    7             print row.name, row.description
    8 
    9 class Application(binding.Component):
   10     db     = binding.Obtain('sqlite:test.db', offerAs=[storage.ISQLConnection])
   11     worker = binding.Make(Worker)
   12 
   13     def run(self):
   14         storage.beginTransaction(self)
   15         self.worker.doWork()
   16         storage.commitTransaction(self)
   17 
   18 if __name__ == '__main__':
   19     from peak.api import config
   20     root = config.makeRoot()
   21     app = Application(root)
   22     app.run()

As subclasses of binding.Component, the Application and Worker classes are capable of taking part in a component hierarchy. Such a hierarchy needs a "root" object at its base -- we use config.makeRoot() to create a component root object on line 20. On line 21 we instantiate an Application object, specifying that root will be its parent. When creating binding.Component-based objects by hand like this, one must always pass a parent object as the first parameter. When using bindings within a class definition (as done on lines 4, 10, and 11) the parent object for the new component will be supplied automatically, if needed.

This small example is already a working database application. It opens a connection to a [WWW]SQLite database file, runs a query against a table, and prints the results. It also demonstrates one of the most useful aspects of the binding package: the ability to create an object once and make use of it in another part of the application. In database applications you usually want a single connection to a database server which will be shared throughout the application. Without binding one would have to either create the connection object and pass it to every new object that needed it, or provide it to the rest of the application using a singleton mechanism of some kind.

The former technique is highly error prone and forces the application to be "tightly coupled" -- that is, objects need to know quite a bit about each other and are usually highly dependent on each other's interfaces and structure. Changing one object in a tightly coupled application often requires changes to a number of other objects, and in large applications these inter-dependencies are not always known by every programmer or are easily missed. Tightly coupled software tends to be extremely brittle as a result.

The singleton approach can help quite a bit by ensuring that only one instance of a certain type of object exists and that it can be found relatively easily. In Python this is often achieved through a separate module and module-level variables. The great drawback of a singleton, however, is that there's only one of it. Classes that use singletons are less reusable, because you can't create instances that use different values for a singleton. (Because then it wouldn't be a singleton!) So, classes that use singletons are still tightly coupled.

What is typically needed in larger applications is a flexible way to create, lookup, and use "singleton-like" objects. PEAK calls such objects "service components", and part of what PEAK's binding package provides is easy access to such components, using looser forms of coupling such as:

When a class embeds all its dependencies in "attribute bindings" like these, the class can easily be reused via subclassing or by simply setting attributes on instances.

... to be continued ...


PythonPowered
EditText of this page (last modified 2005-03-08 15:03:29)
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck