~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/row.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Twisted Enterprise Row Objects</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Twisted Enterprise Row Objects</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Class Definitions</a></li><li><a href="#auto1">Initialization</a></li><li><a href="#auto2">Creating Row Objects</a></li><li><a href="#auto3">Relationships Between Tables</a></li><li><a href="#auto4">Duplicate Row Objects</a></li><li><a href="#auto5">Updating Row Objects</a></li><li><a href="#auto6">Deleting Row Objects</a></li></ol></div>
 
10
    <div class="content">
 
11
 
 
12
<div class="note"><strong>Note: </strong>
 
13
<p>
 
14
Due to lack of maintenance, <code>twisted.enterprise.row</code>
 
15
and <code>twisted.enterprise.reflector</code> have been deprecated since
 
16
Twisted 8.0.
 
17
</p>
 
18
 
 
19
<p>
 
20
This documentation is maintained only for users with an existing
 
21
codebase.
 
22
</p>
 
23
</div>
 
24
 
 
25
 
 
26
<span/>
 
27
 
 
28
<p>The <code>twisted.enterprise.row</code> module is a method of
 
29
interfacing simple python objects with rows in relational database
 
30
tables. It has two components: the <code>RowObject</code> class which
 
31
developers sub-class for each relational table that their code
 
32
interacts with, and the <code>Reflector</code> which is responsible
 
33
for updates, inserts, queries and deletes against the database.</p>
 
34
 
 
35
<p>The row module is intended for applications such as on-line
 
36
games, and websites that require a back-end database interface.
 
37
It is not a full functioned object-relational mapper for python
 
38
- it deals best with simple data types structured in ways that
 
39
can be easily represented in a relational database. It is well
 
40
suited to building a python interface to an existing relational
 
41
database, and slightly less suited to added database persistance
 
42
to an existing python application.</p>
 
43
 
 
44
<p><em>If row does not fit your model, you will be best off using
 
45
the <a href="rdbms.html" shape="rect">low-level database API</a> directly, 
 
46
or writing your own object/relational layer on top of it.</em></p>
 
47
 
 
48
<h2>Class Definitions<a name="auto0"/></h2>
 
49
 
 
50
<p>To interface to relational database tables, the developer must
 
51
create a class derived from the <code>twisted.enterprise.row.RowObject</code>
 
52
class for each table. These derived classes must define a number
 
53
of class attributes which contains information about the database
 
54
table that class corresponds to. The required class attributes
 
55
are:</p>
 
56
 
 
57
<ul>
 
58
  <li>rowColumns - list of the column names and types in the table with
 
59
  the correct case</li>
 
60
  <li>rowKeyColumns - list of key columns in form: <code>[(columnName,
 
61
  typeName)]</code></li>
 
62
  <li>rowTableName - the name of the database table</li>
 
63
</ul>
 
64
 
 
65
<p>There are also two optional class attributes that can be specified:</p>
 
66
 
 
67
<ul>
 
68
  <li>rowForeignKeys - list of foreign keys to other database tables
 
69
   in the form: <code>[(tableName, [(childColumnName, childColumnType), ...], 
 
70
   [(parentColumnName, parentColumnType), ...], containerMethodName, autoLoad]</code></li>
 
71
  <li>rowFactoryMethod - a method that creates instances of this
 
72
  class</li>
 
73
</ul>
 
74
 
 
75
<p>For example:</p>
 
76
 
 
77
<pre class="python"><p class="py-linenumber"> 1
 
78
 2
 
79
 3
 
80
 4
 
81
 5
 
82
 6
 
83
 7
 
84
 8
 
85
 9
 
86
10
 
87
11
 
88
12
 
89
</p><span class="py-src-keyword">class</span> <span class="py-src-identifier">RoomRow</span>(<span class="py-src-parameter">row</span>.<span class="py-src-parameter">RowObject</span>):
 
90
    <span class="py-src-variable">rowColumns</span>       = [(<span class="py-src-string">&quot;roomId&quot;</span>,  <span class="py-src-string">&quot;int&quot;</span>), 
 
91
                        (<span class="py-src-string">&quot;town_id&quot;</span>, <span class="py-src-string">&quot;int&quot;</span>),
 
92
                        (<span class="py-src-string">&quot;name&quot;</span>,    <span class="py-src-string">&quot;varchar&quot;</span>),
 
93
                        (<span class="py-src-string">&quot;owner&quot;</span>,   <span class="py-src-string">&quot;varchar&quot;</span>),
 
94
                        (<span class="py-src-string">&quot;posx&quot;</span>,    <span class="py-src-string">&quot;int&quot;</span>),
 
95
                        (<span class="py-src-string">&quot;posy&quot;</span>,    <span class="py-src-string">&quot;int&quot;</span>),
 
96
                        (<span class="py-src-string">&quot;width&quot;</span>,   <span class="py-src-string">&quot;int&quot;</span>),
 
97
                        (<span class="py-src-string">&quot;height&quot;</span>,  <span class="py-src-string">&quot;int&quot;</span>)]
 
98
    <span class="py-src-variable">rowKeyColumns</span>    = [(<span class="py-src-string">&quot;roomId&quot;</span>,  <span class="py-src-string">&quot;int4&quot;</span>)]
 
99
    <span class="py-src-variable">rowTableName</span>     = <span class="py-src-string">&quot;testrooms&quot;</span>
 
100
    <span class="py-src-variable">rowFactoryMethod</span> = [<span class="py-src-variable">testRoomFactory</span>]
 
101
</pre>
 
102
 
 
103
<p>The items in the rowColumns list will become data members of
 
104
classes of this type when they are created by the Reflector.</p>
 
105
 
 
106
<h2>Initialization<a name="auto1"/></h2>
 
107
 
 
108
<p>The initialization phase builds the SQL for the database interactions.
 
109
It uses the system catalogs of the database to do this, but requires
 
110
some basic information to get started. The class attributes of
 
111
the classes derived from RowClass are used for this. Those classes
 
112
are passed to a Reflector when it is created.</p>
 
113
 
 
114
<p>There are currently two available reflectors in Twisted Enterprise,
 
115
the SQL Reflector for relational databases which uses the python DB
 
116
API, and the XML Reflector which uses a file system containing XML
 
117
files. The XML reflector is currently extremely slow.</p>
 
118
 
 
119
<p>An example class list for the RoomRow class we specified above using the SQLReflector:</p>
 
120
 
 
121
<pre class="python"><p class="py-linenumber">1
 
122
2
 
123
3
 
124
4
 
125
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">enterprise</span>.<span class="py-src-variable">sqlreflector</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">SQLReflector</span>
 
126
 
 
127
<span class="py-src-variable">dbpool</span> = <span class="py-src-variable">adbapi</span>.<span class="py-src-variable">ConnectionPool</span>(<span class="py-src-string">&quot;pyPgSQL.PgSQL&quot;</span>)
 
128
<span class="py-src-variable">reflector</span> = <span class="py-src-variable">SQLReflector</span>( <span class="py-src-variable">dbpool</span>, [<span class="py-src-variable">RoomRow</span>] )
 
129
</pre>
 
130
 
 
131
<h2>Creating Row Objects<a name="auto2"/></h2>
 
132
 
 
133
<p>There are two methods of creating RowObjects - loading from
 
134
the database, and creating a new instance ready to be inserted.</p>
 
135
 
 
136
<p>To load rows from the database and create RowObject instances
 
137
for each of the rows, use the loadObjectsFrom method of the Reflector.
 
138
This takes a tableName, an optional <q>user data</q> parameter,
 
139
and an optional <q>where clause</q>. The where clause may
 
140
be omitted which will retrieve all the rows from the table. For
 
141
example:</p>
 
142
 
 
143
<pre class="python"><p class="py-linenumber">1
 
144
2
 
145
3
 
146
4
 
147
5
 
148
6
 
149
7
 
150
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">gotRooms</span>(<span class="py-src-parameter">rooms</span>):
 
151
    <span class="py-src-keyword">for</span> <span class="py-src-variable">room</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">rooms</span>:
 
152
        <span class="py-src-keyword">print</span> <span class="py-src-string">&quot;Got room:&quot;</span>, <span class="py-src-variable">room</span>.<span class="py-src-variable">id</span>
 
153
 
 
154
<span class="py-src-variable">d</span> = <span class="py-src-variable">reflector</span>.<span class="py-src-variable">loadObjectsFrom</span>(<span class="py-src-string">&quot;testrooms&quot;</span>, 
 
155
                              <span class="py-src-variable">whereClause</span>=[(<span class="py-src-string">&quot;id&quot;</span>, <span class="py-src-variable">reflector</span>.<span class="py-src-variable">EQUAL</span>, <span class="py-src-number">5</span>)])
 
156
<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">gotRooms</span>)
 
157
</pre>
 
158
 
 
159
<p>For more advanced RowObject construction, loadObjectsFrom may
 
160
use a factoryMethod that was specified as a class attribute for
 
161
the RowClass derived class. This method will be called for each
 
162
of the rows with the class object, the userData parameter, and
 
163
a dictionary of data from the database keyed by column name. This
 
164
factory method should return a fully populated RowObject instance
 
165
and may be used to do pre-processing, lookups, and data transformations
 
166
before exposing the data to user code. An example factory method:</p>
 
167
 
 
168
<pre class="python"><p class="py-linenumber">1
 
169
2
 
170
3
 
171
4
 
172
</p><span class="py-src-keyword">def</span> <span class="py-src-identifier">testRoomFactory</span>(<span class="py-src-parameter">roomClass</span>, <span class="py-src-parameter">userData</span>, <span class="py-src-parameter">kw</span>):
 
173
    <span class="py-src-variable">newRoom</span> = <span class="py-src-variable">roomClass</span>(<span class="py-src-variable">userData</span>)
 
174
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">__dict__</span>.<span class="py-src-variable">update</span>(<span class="py-src-variable">kw</span>)
 
175
    <span class="py-src-keyword">return</span> <span class="py-src-variable">newRoom</span>
 
176
</pre>
 
177
 
 
178
<p>The last method of creating a row object is for new instances
 
179
that do not already exist in the database table. In this case,
 
180
create a new instance and assign its primary key attributes and
 
181
all of its member data attributes, then pass it to the <code>insertRow</code>
 
182
method of the Reflector. For example:</p>
 
183
 
 
184
<pre class="python"><p class="py-linenumber"> 1
 
185
 2
 
186
 3
 
187
 4
 
188
 5
 
189
 6
 
190
 7
 
191
 8
 
192
 9
 
193
10
 
194
</p><span class="py-src-variable">newRoom</span> = <span class="py-src-variable">RoomRow</span>()
 
195
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">assignKeyAttr</span>(<span class="py-src-string">&quot;roomI&quot;</span>, <span class="py-src-number">11</span>)
 
196
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">town_id</span> = <span class="py-src-number">20</span>
 
197
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">name</span> = <span class="py-src-string">'newRoom1'</span>
 
198
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">owner</span> = <span class="py-src-string">'fred'</span>
 
199
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">posx</span> = <span class="py-src-number">100</span>
 
200
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">posy</span> = <span class="py-src-number">100</span>
 
201
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">width</span> = <span class="py-src-number">15</span>
 
202
    <span class="py-src-variable">newRoom</span>.<span class="py-src-variable">height</span> = <span class="py-src-number">20</span>
 
203
    <span class="py-src-variable">reflector</span>.<span class="py-src-variable">insertRow</span>(<span class="py-src-variable">newRoom</span>).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">onInsert</span>)
 
204
</pre>
 
205
 
 
206
<p>This will insert a new row into the database table for this
 
207
new RowObject instance. Note that the <code>assignKeyAttr</code>
 
208
method must be used to set primary key attributes - regular attribute
 
209
assignment of a primary key attribute of a rowObject will raise
 
210
an exception. This prevents the database identity of RowObject
 
211
from being changed by mistake.</p>
 
212
 
 
213
 
 
214
<h2>Relationships Between Tables<a name="auto3"/></h2>
 
215
 
 
216
<p>Specifying a foreign key for a RowClass creates a relationship
 
217
between database tables. When <code class="python">loadObjectsFrom</code> is called for a table, it will
 
218
automatically load all the children rows for the rows from the specified
 
219
table. The child rows will be put into a list member variable of the
 
220
rowObject instance with the name <code>childRows</code> or if a
 
221
<em>containerMethod</em> is specified for the foreign key relationship,
 
222
that method will be called on the parent row object for each row that is
 
223
being added to it as a child.</p>
 
224
 
 
225
<p>The <em>autoLoad</em> member of the foreign key definition is a flag
 
226
that specifies whether child rows should be auto-loaded for that
 
227
relationship when a parent row is loaded.</p>
 
228
 
 
229
<h2>Duplicate Row Objects<a name="auto4"/></h2>
 
230
 
 
231
<p>If a reflector tries to load an instance of a rowObject that
 
232
is already loaded, it will return a reference to the existing
 
233
rowObject rather than creating a new instance. The reflector maintains
 
234
a cache of weak references to all loaded row objects by their
 
235
unique keys for this purpose.</p>
 
236
 
 
237
<h2>Updating Row Objects<a name="auto5"/></h2>
 
238
 
 
239
<p>RowObjects have a <code>dirty</code> member attribute that is
 
240
set to 1 when any of the member attributes of the instance that
 
241
map to database columns are changed. This dirty flag can be used
 
242
to tell when RowObjects need to be updated back to the database.
 
243
In addition, the <code>setDirty</code> method can be overridden
 
244
to provide more complex automated handling such as dirty lists
 
245
(be sure to call the base class setDirty though!).</p>
 
246
 
 
247
<p>When it is determined that a RowObject instance is dirty and
 
248
need to have its state updated into the database, pass that object
 
249
to the <code>updateRow</code> method of the Reflector. For example:</p>
 
250
 
 
251
<pre class="python"><p class="py-linenumber">1
 
252
</p><span class="py-src-variable">reflector</span>.<span class="py-src-variable">updateRow</span>(<span class="py-src-variable">room</span>).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">onUpdated</span>)
 
253
</pre>
 
254
 
 
255
<p>For more complex behavior, the reflector can generate the SQL
 
256
for the update but not perform the update. This can be useful
 
257
for batching up multiple updates into single requests. For example:</p>
 
258
 
 
259
<pre class="python"><p class="py-linenumber">1
 
260
</p><span class="py-src-variable">updateSQL</span> = <span class="py-src-variable">reflector</span>.<span class="py-src-variable">updateRowSQL</span>(<span class="py-src-variable">room</span>)
 
261
</pre>
 
262
 
 
263
<h2>Deleting Row Objects<a name="auto6"/></h2>
 
264
 
 
265
<p>To delete a row from a database pass the RowObject instance
 
266
for that row to the Reflector <code>deleteRow</code> method.
 
267
Deleting the python Rowobject instance does <em>not</em> automatically
 
268
delete the row from the database. For example:</p>
 
269
 
 
270
<pre class="python"><p class="py-linenumber">1
 
271
</p><span class="py-src-variable">reflector</span>.<span class="py-src-variable">deleteRow</span>(<span class="py-src-variable">room</span>)
 
272
</pre>
 
273
 
 
274
</div>
 
275
 
 
276
    <p><a href="index.html">Index</a></p>
 
277
    <span class="version">Version: 10.0.0</span>
 
278
  </body>
 
279
</html>
 
 
b'\\ No newline at end of file'