Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZODB
Commits
32ddff9f
Commit
32ddff9f
authored
Jan 06, 2004
by
Jeremy Hylton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
A bunch of changes to bring into line with ZODB 3.3 naming.
parent
02351cf5
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
96 additions
and
92 deletions
+96
-92
doc/guide/introduction.tex
doc/guide/introduction.tex
+4
-3
doc/guide/links.tex
doc/guide/links.tex
+0
-7
doc/guide/modules.tex
doc/guide/modules.tex
+2
-2
doc/guide/prog-zodb.tex
doc/guide/prog-zodb.tex
+60
-70
doc/guide/storages.tex
doc/guide/storages.tex
+1
-1
doc/guide/zeo.tex
doc/guide/zeo.tex
+28
-8
doc/guide/zodb.tex
doc/guide/zodb.tex
+1
-1
No files found.
doc/guide/introduction.tex
View file @
32ddff9f
...
...
@@ -33,8 +33,9 @@ this.
The downside is that the programmer has to explicitly manage objects,
reading an object when it's needed and writing it out to disk when the
object is no longer required. The ZODB manages objects for you,
keeping them in a cache and writing them out if they haven't been
accessed in a while.
keeping them in a cache, writing them out to disk when they are
modified, and dropping them from the cache if they haven't been used
in a while.
\subsection
{
OODBs vs. Relational DBs
}
...
...
@@ -155,7 +156,7 @@ The ZODB comes with a few different classes that implement the
\class
{
Storage
}
interface. Such classes handle the job of
writing out Python objects to a physical storage medium, which can be
a disk file (the
\class
{
FileStorage
}
class), a BerkeleyDB file
(
\class
{
B
erkeley
Storage
}
), a relational database
(
\class
{
B
DBFull
Storage
}
), a relational database
(
\class
{
DCOracleStorage
}
), or some other medium. ZEO adds
\class
{
ClientStorage
}
, a new
\class
{
Storage
}
that doesn't write to
physical media but just forwards all requests across a network to a
...
...
doc/guide/links.tex
View file @
32ddff9f
...
...
@@ -3,13 +3,6 @@
\section
{
Resources
}
ZODB HOWTO, by Michel Pelletier:
\\
Goes into slightly more detail about the rules for writing applications using the ZODB.
\\
\url
{
http://www.zope.org/Members/michel/HowTos/ZODB-How-To
}
Introduction to the Zope Object Database, by Jim Fulton:
\\
Goes into much greater detail, explaining advanced uses of the ZODB and
...
...
doc/guide/modules.tex
View file @
32ddff9f
...
...
@@ -9,7 +9,7 @@
The ZODB package includes a number of related modules that provide
useful data types such as BTrees.
\subsection
{
\module
{
ZODB
.PersistentMapping
}}
\subsection
{
\module
{
persistent.mapping
.PersistentMapping
}}
The
\class
{
PersistentMapping
}
class is a wrapper for mapping objects
that will set the dirty bit when the mapping is modified by setting or
...
...
@@ -24,7 +24,7 @@ value for \var{container}, a regular Python dictionary is used.
\class
{
PersistentMapping
}
objects support all the same methods as
Python dictionaries do.
\subsection
{
\module
{
ZODB
.PersistentList
}}
\subsection
{
\module
{
persistent.list
.PersistentList
}}
The
\class
{
PersistentList
}
class is a wrapper for mutable sequence objects,
much as
\class
{
PersistentMapping
}
is a wrapper for mappings.
...
...
doc/guide/prog-zodb.tex
View file @
32ddff9f
...
...
@@ -13,7 +13,7 @@ ZODB is packaged using the standard distutils tools.
\subsubsection
{
Requirements
}
You will need Python 2.
2
or higher. Since the code is packaged using
You will need Python 2.
3
or higher. Since the code is packaged using
distutils, it is simply a matter of untarring or unzipping the release
package, and then running
\code
{
python setup.py install
}
.
...
...
@@ -34,12 +34,12 @@ the ZODB Wiki at \url{http://www.zope.org/Wikis/ZODB}.
\subsection
{
How ZODB Works
}
The ZODB is conceptually simple. Python classes subclass a
\class
{
Persistent
}
class to become ZODB-aware.
\class
{
persistent.
Persistent
}
class to become ZODB-aware.
Instances of persistent objects are brought in from a permanent
storage medium, such as a disk file, when the program needs them, and
remain cached in RAM. The ZODB traps modifications to objects, so
that when a statement such as
\code
{
obj.size = 1
}
is executed, the
modified object is marked as ``dirty
''.
On request, any dirty objects
modified object is marked as ``dirty
.''
On request, any dirty objects
are written out to permanent storage; this is called committing a
transaction. Transactions can also be aborted or rolled back, which
results in any changes being discarded, dirty objects reverting to
...
...
@@ -97,7 +97,7 @@ implement the \class{Storage} interface.
storing and retrieving objects from some form of long-term storage.
A few different types of Storage have been written, such as
\class
{
FileStorage
}
, which uses regular disk files, and
\class
{
bsddb3
Storage
}
, which uses Sleepycat Software's BerkeleyDB
\class
{
BDBFull
Storage
}
, which uses Sleepycat Software's BerkeleyDB
database. You could write a new Storage that stored objects in a
relational database, for example, if that would
better suit your application. Two example storages,
...
...
@@ -134,27 +134,54 @@ changing the first line that opens a \class{Storage}; the above example uses a
\class
{
FileStorage
}
. In section~
\ref
{
zeo
}
, ``How ZEO Works'',
you'll see how ZEO uses this flexibility to good effect.
\subsection
{
Using a ZODB Configuration File
}
ZODB also supports configuration files written in the ZConfig format.
A configuration file can be used to separate the configuration logic
from the application logic. The storages classes and the
\class
{
DB
}
class support a variety of keyword arguments; all these options can be
specified in a config file.
The configuration file is simple. The example in the previous section
could use the following example:
\begin{verbatim}
<zodb>
<filestorage>
path /tmp/test-filestorage.fs
</filestorage>
</zodb>
\end{verbatim}
The
\module
{
ZODB.config
}
module includes several functions for opening
database and storages from configuration files.
\begin{verbatim}
import ZODB.config
db = ZODB.config.databaseFromURL('/tmp/test.conf')
conn = db.open()
\end{verbatim}
The ZConfig documentation, included in the ZODB3 release, explains
the format in detail. Each configuration file is described by a
schema, by convention stored in a
\file
{
component.xml
}
file. ZODB,
ZEO, zLOG, and zdaemon all have schemas.
\subsection
{
Writing a Persistent Class
}
Making a Python class persistent is quite simple; it simply needs to
subclass from the
\class
{
Persistent
}
class, as shown in this example:
\begin{verbatim}
import ZODB
from Persistence import Persistent
from persistent import Persistent
class User(Persistent):
pass
\end{verbatim}
The apparently unnecessary
\code
{
import ZODB
}
statement is
needed for the following
\code
{
from...import
}
statement to work
correctly, since the ZODB code does some magical tricks with
importing.
The
\class
{
Persistent
}
base class is an
\module
{
ExtensionClass
}
class. As a result, it not compatible with new-style classes or types
in Python 2.2 and up.
The
\class
{
Persistent
}
base class is a new-style class implemented in
C.
For simplicity, in the examples the
\class
{
User
}
class will
simply be used as a holder for a bunch of attributes. Normally the
...
...
@@ -246,25 +273,27 @@ in practice it isn't too painful to work around them.
The summary of rules is as follows:
\begin{itemize}
\item
If you modify a mutable object that's the value of an object's
attribute, the ZODB can't catch that, and won't mark the object as
dirty.
The solution is to either set the dirty bit yourself when you modify
mutable objects, or use a wrapper for Python's lists and dictionaries
(
\class
{
PersistentList
}
,
dirty. The solution is to either set the dirty bit yourself when you
modify mutable objects, or use a wrapper for Python's lists and
dictionaries (
\class
{
PersistentList
}
,
\class
{
PersistentMapping
}
)
that will set the dirty bit properly.
\item
Certain of Python's special methods don't work when they're
defined on ExtensionClasses. The most important ones are the
\method
{__
cmp
__}
method, and the reversed versions of binary
arithmetic operations:
\method
{__
radd
__}
,
\method
{__
rsub
__}
, and so
forth.
\item
Recent versions of the ZODB allow writing a class with
\method
{__
setattr
__}
,
\method
{__
getattr
__}
, or
\method
{__
delattr
__}
methods. (Older versions didn't support this at all.)
If you write such a
\method
{__
setattr
__}
or
\method
{__
delattr
__}
method,
its code has to set the dirty bit manually,
\method
{__
setattr
__}
,
\method
{__
getattr
__}
, or
\method
{__
delattr
__}
methods. (Older versions didn't support this at all.) If you write
such a
\method
{__
setattr
__}
or
\method
{__
delattr
__}
method, its code
has to set the dirty bit manually.
\item
A persistent class should not have an
\method
{__
del
__}
method.
The database moves objects freely between memory and storage. If an
object has not been used in a while, it may be released and its
contents loaded from storage the next time it is used. Since the
Python interpreter is unaware of persistence, it would call the
\method
{__
del
__}
each time the object was freed.
\end{itemize}
...
...
@@ -296,13 +325,9 @@ its dirty bit to true. This is done by setting the
\begin{verbatim}
userobj.friends.append(otherUser)
userobj.
_
p
_
changed =
1
userobj.
_
p
_
changed =
True
\end{verbatim}
An obsolete way of doing this that's still supported is calling the
\method
{__
changed
__
()
}
method instead, but setting
\member
{_
p
_
changed
}
is the preferred way.
You can hide the implementation detail of having to mark objects as
dirty by designing your class's API to not use direct attribute
access; instead, you can use the Java-style approach of accessor
...
...
@@ -328,46 +353,11 @@ and may make it into a future upstream release of Zope.
% you set an object's _p_changed = None). The __p_deactivate__ method should
% not be used (it's also obsolete).
\subsubsection
{
Some Special Methods Don't Work
}
Don't bother defining certain special methods on
ExtensionClasses, because they won't work. Most notably, the
\method
{__
cmp
__}
method on an ExtensionClass will never be called.
Neither will the reversed versions of binary arithmetic operations,
such as
\method
{__
radd
__}
and
\method
{__
rsub
__}
.
This is a moderately annoying limitation. It means that the
\class
{
PersistentList
}
class can't implement comparisons with regular
sequence objects, and therefore statements such as
\verb
|
if perslist==[]
|
don't do what you expect; instead of performing the correct
comparison, they return some arbitrary fixed result, so the
\code
{
if
}
statement will always be true or always be false. There is no good
solution to this problem at the moment, so all you can do is design
class interfaces that don't need to overload
\method
{__
cmp
__}
or the
\method
{__
r*
__}
methods.
This limitation is mostly Python's fault. As of Python 2.1, the most
recent version at this writing, the code which handles comparing two
Python objects contains a hard-wired check for objects that are class
instances, which means that
\code
{
type(obj) == types.InstanceType
}
.
The code inside the Python interpreter looks like this:
\begin{verbatim}
/* Code to compare objects v and w */
if (PyInstance
_
Check(v) || PyInstance
_
Check(w))
return PyInstance
_
DoBinOp(v, w, "
__
cmp
__
", "
__
rcmp
__
", do
_
cmp);
/* Do usual Python comparison of v,w */
c = PyObject
_
Compare(v, w);
\end{verbatim}
While ExtensionClasses try to behave as much like regular Python
instances as possible, they are still not instances, and
\function
{
type()
}
doesn't return the
\code
{
InstanceType
}
object, so
no attempt is ever made to call
\method
{__
cmp
__}
. Perhaps Python 2.2
will repair this.
\subsubsection
{
\method
{__
getattr
__}
,
\method
{__
delattr
__}
, and
\method
{__
setattr
__}}
% XXX This section could be out-of-date. I've got to remember how we
% decided to do this before the beta release.
Recent versions of ZODB allow writing persistent classes that have
\method
{__
getattr
__}
,
\method
{__
delattr
__}
, or
\method
{__
setattr
__}
methods. The one minor complication is that the machinery for
...
...
doc/guide/storages.tex
View file @
32ddff9f
...
...
@@ -16,7 +16,7 @@ XXX explain mounting substorages
\subsection
{
FileStorage
}
\subsection
{
B
erkeley
Storage
}
\subsection
{
B
DBFull
Storage
}
\subsection
{
OracleStorage
}
doc/guide/zeo.tex
View file @
32ddff9f
...
...
@@ -18,7 +18,7 @@ them in a distributed fashion without Zope ever entering the picture.
The combination of ZEO and ZODB is essentially a Python-specific
object database.
ZEO consists of about
6
000 lines of Python code, excluding tests. The
ZEO consists of about
12,
000 lines of Python code, excluding tests. The
code is relatively small because it contains only code for a TCP/IP
server, and for a new type of Storage,
\class
{
ClientStorage
}
.
\class
{
ClientStorage
}
simply makes remote procedure calls to the
...
...
@@ -45,9 +45,9 @@ writes, and ZEO is therefore better suited for read-intensive
applications. If every
\class
{
ClientStorage
}
is writing to the
database all the time, this will result in a storm of invalidate
messages being sent, and this might take up more processing time than
the actual database operations themselves.
\footnote
{
These messages are
the actual database operations themselves.
These messages are
small and sent in batches, so there would need to be a lot of writes
before it became a problem.
}
before it became a problem.
On the other hand, for applications that have few writes in comparison
to the number of read accesses, this aggressive caching can be a major
...
...
@@ -71,15 +71,15 @@ configure and run a ZEO Storage Server on a machine.
\subsubsection
{
Requirements
}
The ZEO server software is included in ZODB3. As with the rest of
ZODB3, you'll need Python 2.
1
or higher.
ZODB3, you'll need Python 2.
3
or higher.
\subsubsection
{
Running a server
}
The
start
.py script in the ZEO directory can be used to start a
The
runzeo
.py script in the ZEO directory can be used to start a
server. Run it with the -h option to see the various values. If
you're just experimenting, a good choise is to use
\code
{
python ZEO/
start.py -D -U /tmp/zeosocket
}
to run ZEO i
n
debug mode and with a Unix domain socket
.
\code
{
python ZEO/
runzeo.py -a /tmp/zeosocket -f /tmp/test.fs
}
to ru
n
ZEO with a Unix domain socket and a
\class
{
FileStorage
}
.
\subsection
{
Testing the ZEO Installation
}
...
...
@@ -101,7 +101,7 @@ from ZEO import ClientStorage
from ZODB import DB
# Change next line to connect to your ZEO server
addr =
('kronos.example.com', 1975)
addr =
'kronos.example.com', 1975
storage = ClientStorage.ClientStorage(addr)
db = DB(storage)
conn = db.open()
...
...
@@ -117,6 +117,26 @@ get_transaction().commit()
If this code runs properly, then your ZEO server is working correctly.
You can also use a configuration file.
\begin{verbatim}
<zodb>
<zeoclient>
server localhost:9100
</zeoclient>
</zodb>
\end{verbatim}
One nice feature of the configuration file is that you don't need to
specify imports for a specific storage. That makes the code a little
shorter and allows you to change storages without changing the code.
\begin{verbatim}
import ZODB.config
db = ZODB.config.databaseFromURL('/tmp/zeo.conf')
\end{verbatim}
\subsection
{
ZEO Programming Notes
}
ZEO is written using
\module
{
asyncore
}
, from the Python standard
...
...
doc/guide/zodb.tex
View file @
32ddff9f
\documentclass
{
howto
}
\title
{
ZODB/ZEO Programming Guide
}
\release
{
0.2
}
\release
{
0.
3a
2
}
\date
{
\today
}
\author
{
A.M.
\
Kuchling
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment