Author: ianb
Date: 2004-11-11 13:57:53 -0500 (Thu, 11 Nov 2004)
New Revision: 364
Modified:
trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-progr=
amming.html
trunk/SQLObject/docs/presentation-2004-11/ui/custom.css
trunk/SQLObject/docs/presentation-2004-11/ui/framing.css
trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css
Log:
Edits and visual updates
Modified: trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-databas=
e-programming.html
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-prog=
ramming.html 2004-11-11 18:38:24 UTC (rev 363)
+++ trunk/SQLObject/docs/presentation-2004-11/sqlobject-and-database-prog=
ramming.html 2004-11-11 18:57:53 UTC (rev 364)
@@ -11,7 +11,7 @@
<link rel=3D"stylesheet" href=3D"ui/print.css" type=3D"text/css"
media=3D"print" id=3D"slidePrint" />
<link rel=3D"stylesheet" href=3D"ui/custom.css" type=3D"text/css"/>
-<sc ript src=3D"ui/slides.js" type=3D"text/javascript"></script>
+<script src=3D"ui/slides.js" type=3D"text/javascript"></script>
</head>
<body>
=20
@@ -62,7 +62,7 @@
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
<div class=3D"slide">
-<h1>Database Programming in Python</h1>
+<h1>The DB API</h1>
=20
<p>Database programming in Python is based on the <b><a
href=3D"http://www.python.org/peps/pep-0249.html">DB-API</a></b>.
@@ -72,11 +72,9 @@
<li>MySQL</li>
<li>PostgreSQL (multiple drivers)</li>
<li>SQLite</li>
-<li>Oracle</li>
-<li>Sybase</li>
<li>Firebird (Interbase)</li>
<li>MAXDB (SAP DB)</li>
-<li>MS SQL Server</li>
+<li>Oracle, Sybase, MS SQL Server</li>
</p>
</div>
=20
@@ -109,7 +107,7 @@
<h1>DB API</h1>
=20
<ul>
-<li> Import the databse module (<code>MySQLdb</code>,
+<li> Import the database module (<code>MySQLdb</code>,
<code>psycopg</code>, <code>sqlite</code>, etc) </li>
<li> Use <code>module.connect(...)</code> to create a
connection. </li>
@@ -194,12 +192,14 @@
=20
<div class=3D"slide">
=20
-<h1>Object-Relational Mappers: Classes</h1>
+<h1>ORMs: Classes</h1>
=20
<p>
=20
The class:
=20
+<table width=3D"100%">
+<tr><td>
<table border=3D1>
=20
<tr class=3D"code-accent"><th colspan=3D3>person</th></tr>
@@ -225,14 +225,16 @@
</tr>
=20
</table>
-<p>
+</td>
=20
+<td>
<pre>
class Person(SQLObject):
<span class=3D"comment"># id is implicit</span>
first_name =3D StringCol()
last_name =3D StringCol()
</pre>
+</td></tr></table>
=20
</div>
=20
@@ -241,12 +243,15 @@
=20
<div class=3D"slide">
=20
-<h1>Object-Relational Mappers: Instances</h1>
+<h1>ORMs: Instances</h1>
=20
<p>
=20
An instance:
=20
+<table width=3D"100%">
+<tr><td>
+
<table border=3D1>
=20
<tr><th colspan=3D3>person</th></tr>
@@ -272,13 +277,17 @@
</tr>
=20
</table>
-<p>
=20
+</td><td>
+
<pre>
-john =3D Person.get(1)
-assert john.first_name =3D=3D <span class=3D"string">'John'</span>
+<span class=3D"prompt">>>></span> john =3D Person.get(1)
+<span class=3D"prompt">>>></span> john.first_name
+<span class=3D"output">'John'</span>
</pre>
=20
+</td></tr></table>
+</p>
=20
</div>
=20
@@ -286,7 +295,7 @@
=20
=20
<div class=3D"slide">
-<h1>Object-Relational Mapping: summary</h1>
+<h1>ORM: summary</h1>
=20
<ul>
<li>Every table is a class</li>
@@ -308,10 +317,32 @@
first_name =3D StringCol()
last_name =3D StringCol()
emails =3D MultipleJoin('Email')
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Usage (classes)</h1>
+
+<pre>
class Email(SQLObject):
person =3D ForeignKey(<span class=3D"string">'Person'</span>)
type =3D EnumCol(['home', 'work'])
address =3D StringCol()
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Usage (creating tables)</h1>
+
+<pre>
def createTables():
for table in (Person, Email):
table.createTable(ifNotExists=3DTrue)
@@ -322,7 +353,7 @@
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
<div class=3D"slide">
-<h1>More use...</h1>
+<h1>Usage (instances)</h1>
=20
Using your classes:
=20
@@ -332,6 +363,17 @@
<span class=3D"prompt">...</span> address=3D<span class=3D"string">'=
jo...@wo...'</span>)
<span class=3D"prompt">>>></span> john.emails
<span class=3D"output">[]</span>
+</pre>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Usage (instances)</h1>
+
+<pre>
<span class=3D"prompt">>>></span> tom =3D Person(first_name=3D<=
span class=3D"string">'Tom'</span>, last_name=3D<span class=3D"string">'J=
ones'</span>)
<span class=3D"prompt">>>></span> tom is Person.get(tom.id)
<span class=3D"output">True</span>
@@ -342,8 +384,6 @@
</div>
=20
=20
-
-
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
=20
@@ -373,13 +413,17 @@
return self.first_name + ' ' + self.last_name
</pre>
=20
+<pre>
+<span class=3D"prompt">>>></span> tom.name
+<span class=3D"output">'Tom Jones'</span>
+</pre>
=20
</div>
=20
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
<div class=3D"slide">
-<h1></h1>
+<h1>Automatic properties</h1>
=20
<ul>
<li> <code>_get_attr()</code> methods are called whenever the
@@ -487,36 +531,38 @@
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
<div class=3D"slide">
-<h1>Lazy classes</h1>
+<h1>Many-to-many...</h1>
=20
<p>
-SQLObject can use reflection to figure out what columns your table
-has:
+The intermediate table created:
=20
<pre>
-class Person(SQLObject):
- _fromDatabase =3D True
+CREATE TABLE address_person (
+ address_id INT NOT NULL,
+ person_id INT NOT NULL
+);
</pre>
-
</p>
=20
</div>
=20
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
-
<div class=3D"slide">
-<h1>Many-to-many...</h1>
+<h1>Lazy classes</h1>
=20
<p>
-The intermediate table created:
+SQLObject can use reflection to figure out what columns your table
+has:
=20
<pre>
-CREATE TABLE address_person (
- address_id INT NOT NULL,
- person_id INT NOT NULL
-);
+class Person(SQLObject):
+ _fromDatabase =3D True
</pre>
+
+You can start with <code>_fromDatabase =3D True</code> and add=20
+in explicit columns, overriding defaults.
+
</p>
=20
</div>
@@ -524,6 +570,7 @@
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
=20
+
<div class=3D"slide">
<h1>Instances</h1>
=20
@@ -542,12 +589,13 @@
<h1>Updating</h1>
=20
<ul>
-<li>Use <code>aPerson.first_name =3D <span
-class=3D"string">"new_name"</span></code></li>
-<li>Use <code>aPerson.set(first_name=3D<span
+<li><code>aPerson.first_name =3D <span
+class=3D"string">"new_name"</span></code><br>
+ <code class=3D"sql">UPDATE</code> is executed immediately </li>
+<li> Update multiple columns at once: <br>
+<code>aPerson.set(first_name=3D<span
class=3D"string">"new_fname"</span>, last_name=3D<span
-class=3D"string">"new_lname"</span>)</code> for multiple simultaneous
-updates. </li>
+class=3D"string">"new_lname"</span>)</code> </li>
</ul>
=20
</div>
@@ -580,7 +628,7 @@
<p>
=20
<ul>
-<li><code>Class.<b>q</b>.<i>column_name</i></code> creates a magical
+<li><code>Class.<b style=3D"color: #990000">q</b>.column_name</code> cre=
ates a magical
object that creates queries.</li>
<li><code>sqlrepr()</code> turns these query objects into SQL (mostly
hidden)</li>
@@ -625,13 +673,13 @@
<div class=3D"slide">
<h1>SelectResult</h1>
=20
-Select results are fancy.
+Select results are more than just lists:
=20
<ul>
<li> You can slice them, and <code class=3D"sql">LIMIT</code> and <code
class=3D"sql">OFFSET</code> statements are added to your query</li>
<li> You can iterate through them, and avoid loading all objects into
-memory</li>
+memory </li>
<li> You can do things like <code>select_result.count()</code> to run
aggregate functions </li>
<li> To get a real list, you must do <code>list(select_result)</code></l=
i>
@@ -673,16 +721,14 @@
=20
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
-
<div class=3D"slide">
-<h1>Solving the question by avoidance</h1>
+<h1>The problem with ORMs</h1>
=20
-<ul>
- <li> SQLObject doesn't let you forget SQL </li>
- <li> You still have to think relationally </li>
- <li> But many relational concepts don't work either </li>
- <li> Advantage: it's easy </li>
-</ul>
+<p>
+ORMs live in the world between Object Oriented programmers (and
+programs) and Relational programmers (and programs). Neither will be
+happy.
+</p>
=20
</div>
=20
@@ -695,8 +741,6 @@
<ul>
<li> Python classes aren't tables</li>
<li> Python instances aren't rows</li>
- <li> Primitive values (like <code class=3D"string">"John"</code>)
- aren't part of the ORM at all </li>
<ul>
=20
</div>
@@ -711,7 +755,7 @@
<li> Databases don't have inheritance </li>
<li> Even when they do, no one uses it </li>
<li> Some tables are too boring (e.g., intermediate tables for
- many-to-many relationships) </li>
+ many-to-many relationships), or don't warrant the overhead </li>
</ul>
=20
</div>
@@ -723,7 +767,8 @@
=20
<ul>
<li> Instances get garbage collected, rows are forever </li>
- <li> Instances can't be pre-allocated </li>
+ <li> Rows exist even when instances don't </li>
+ <li> Instances may still exist when the row is gone </li>
<li> In the relational calculus, rows don't have real identity </li>
=20
</div>
@@ -738,13 +783,29 @@
<li> Things like joins don't make sense for objects, but are central
to relations </li>
<li> Views and stored procedures also don't make sense </li>
+ <li> Aggregate functions and set operations aren't natural in Python=20
+ (the <code>for</code> loop is natural) </li>
</ul>
=20
</div>
=20
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
+<div class=3D"slide">
+<h1>Solving the question by avoidance</h1>
=20
+<ul>
+ <li> SQLObject doesn't let you forget SQL </li>
+ <li> You still have to think relationally </li>
+ <li> But many relational concepts don't work either </li>
+ <li> Advantage: it's easy </li>
+</ul>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
<div class=3D"slide">
<h1>Solving the Mismatch</h1>
=20
@@ -753,17 +814,50 @@
<ul>
<li> There exist database restrictions; not every database schema maps
well. (But most are fine) </li>
+ <li> Sometimes you have to do things more slowly or more imperatively,
+ compared to a purely relational technique </li>
<li> There exist object restrictions; not every object-oriented
- concept maps well; e.g., no inheritance. </li>
+ concept maps well; e.g., no inheritance </li>
+ <li> Inheritance isn't planned; this isn't transparent persistence </li=
>
</ul>
=20
</div>
=20
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
=20
+<div class=3D"slide">
+<h1>Some other alternatives</h1>
=20
+Several Python ORMs exist; contrasts:=20
+<ul>
+ <li> SQLObject doesn't try to be too OO, so it works well with normal=20
+ database schemas </li>
+ <li> SQLObject doesn't have a compile step </li>
+ <li> SQLObject isn't <i>just</i> a SQL wrapper </li>
+ <li> SQLObject is reasonably complete </li>
+</ul>
=20
</div>
=20
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+<div class=3D"slide">
+<h1>Other alternatives...</h1>
+
+<p>
+
+See the Python Wiki at: <a href=3D"http://python.org/moin">python.org/mo=
in</a><br>
+The page is <a href=3D"http://python.org/moin/HigherLevelDatabaseProgram=
ming">HigherLevelDatabaseProgramming</a>.
+</p>
+
+</div>
+
+<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -->
+
+
+
+</div>
+
</body>
</html>
Modified: trunk/SQLObject/docs/presentation-2004-11/ui/custom.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/custom.css 2004-11-11 18=
:38:24 UTC (rev 363)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/custom.css 2004-11-11 18=
:57:53 UTC (rev 364)
@@ -1,3 +1,7 @@
+td {
+ vertical-align: top;
+}
+
.string {=20
color: #006600;
}
@@ -16,7 +20,7 @@
}
=20
.sql {=20
- color: #006600;
+ color: #004466;
font-weight: bold;
}
=20
Modified: trunk/SQLObject/docs/presentation-2004-11/ui/framing.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/framing.css 2004-11-11 1=
8:38:24 UTC (rev 363)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/framing.css 2004-11-11 1=
8:57:53 UTC (rev 364)
@@ -4,15 +4,15 @@
to help you with the rearrangement process. */
=20
div#header, div#footer, div.slide {width: 100%; top: 0; left: 0;}
-div#header {top: 0; height: 3em; z-index: 1;}
-div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
+div#header {top: 0; height: 2em; z-index: 1;}
+div#footer {top: auto; bottom: 0; height: 1.75em; z-index: 5;}
div.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2;}
div#controls {left: 50%; top: 0; width: 50%; height: 100%; z-index: 1;}
#footer>div#controls {bottom: 0; top: auto; height: auto;}
=20
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
margin: 0;}
-#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z=
-index: 10;}
+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1.5em;=
z-index: 10;}
html>body #currentSlide {position: fixed;}
=20
/*
Modified: trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css 2004-11-11 18=
:38:24 UTC (rev 363)
+++ trunk/SQLObject/docs/presentation-2004-11/ui/pretty.css 2004-11-11 18=
:57:53 UTC (rev 364)
@@ -2,7 +2,8 @@
Note that the 'body' font size may have to be changed if the resoluti=
on is
different than expected. */
=20
-body {background: #fff url(bodybg.gif) -16px 0 no-repeat; color: #000; f=
ont-size: 2em;}
+/* url(bodybg.gif) */
+body {background: #fff -16px 0 no-repeat; color: #000; font-size: 2em;}
:link, :visited {text-decoration: none;}
#controls :active {color: #88A !important;}
#controls :focus {outline: 1px dotted #227;}
@@ -31,17 +32,17 @@
ul ul li {margin: .2em; font-size: 85%; list-style: square;}
img.leader {display: block; margin: 0 auto;}
=20
-div#header, div#footer {background: #005; color: #AAB;
+div#header, div#footer {background: #005; color: #BBC;
font-family: Verdana, Helvetica, sans-serif;}
-div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;
+div#header {background: #005 -16px 0 no-repeat;
line-height: 1px;}
div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}
#footer h1, #footer h2 {display: block; padding: 0 1em;}
#footer h2 {font-style: italic;}
=20
div.long {font-size: 0.75em;}
-.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;
- margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;
+.slide h1 {position: absolute; top: 0.0em; left: 0px; z-index: 1;
+ margin: 0; padding: 0.3em 0 0 10px; white-space: nowrap;
font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;
color: #DDE; background: #005;}
.slide h3 {font-size: 130%;}
@@ -54,13 +55,13 @@
top: auto; height: auto;}
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
margin: 0; padding: 0;}
-div#controls a {font-size: 2em; padding: 0; margin: 0 0.5em;=20
+div#controls a {font-size: 1.7em; padding: 0; margin: 0 0.5em;=20
background: #005; border: none; color: #779;=20
cursor: pointer;}
div#controls select {visibility: hidden; background: #DDD; color: #227;}
div#controls div:hover select {visibility: visible;}
=20
-#currentSlide {text-align: center; font-size: 0.5em; color: #449;}
+#currentSlide {text-align: center; font-size: 0.5em; color: #77B;}
=20
#slide0 {padding-top: 3.5em; font-size: 90%;}
#slide0 h1 {position: static; margin: 1em 0 1.33em; padding: 0;
|