Skip to content

Commit 57d5e71

Browse files
committed
Preen docs on orm
1 parent 539b289 commit 57d5e71

File tree

1 file changed

+38
-23
lines changed

1 file changed

+38
-23
lines changed

postgres/orm.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
""":py:mod:`postgres` implements an object-relational mapper based on
22
:py:mod:`psycopg2` composite casters. The fundamental technique, introduced by
33
`Michael Robbelard at PyOhio 2013`_, is to write SQL queries that typecast
4-
results to table types, and then use :py:mod:`psycopg2`
4+
results to table types, and then use a :py:mod:`psycopg2`
55
:py:class:`~psycopg2.extra.CompositeCaster` to map these to Python objects.
66
This means we get to define our schema in SQL, and we get to write our queries
77
in SQL, and we get to explicitly indicate in our SQL queries how Python should
8-
map the result to an object, and then we can write Python objects that contain
8+
map the results to objects, and then we can write Python objects that contain
99
only business logic and not schema definitions.
1010
1111
.. _Michael Robbelard at PyOhio 2013: https://www.youtube.com/watch?v=Wz1_GYc4GmU#t=25m06s
1212
1313
Every table in PostgreSQL has a type associated with it, which is the column
14-
definition for that table. These are composite types just like any other in
15-
PostgreSQL, meaning we can use them to cast query results. When we do, we get a
16-
single field that contains our query data, nested one level::
14+
definition for that table. These are composite types just like any other
15+
composite type in PostgreSQL, meaning we can use them to cast query results.
16+
When we do, we get a single field that contains our query result, nested one
17+
level::
1718
1819
test=# CREATE TABLE foo (bar text, baz int);
1920
CREATE TABLE
@@ -68,7 +69,7 @@
6869
:py:mod:`psycopg2` provides a :py:func:`~psycopg2.extras.register_composite`
6970
function that lets us map PostgreSQL composite types to Python objects. This
7071
includes table and view types, and that is the basis for
71-
:py:mod:`postgres.orm`.
72+
:py:mod:`postgres.orm`. We map based on types, not tables.
7273
7374
7475
ORM Tutorial
@@ -82,20 +83,20 @@
8283
...
8384
8485
Your model must have a :py:attr:`typname` attribute, which is the name of the
85-
PostgreSQL type that this class is intended to be an object mapping for.
86-
(``typname`` is the name of the relevant column in the ``pg_type`` table in
87-
your database.)
86+
PostgreSQL type for which this class is an object mapping. (``typname``,
87+
spelled without an "e," is the name of the relevant column in the ``pg_type``
88+
table in your database.)
8889
8990
Second, register your model with your :py:class:`~postgres.Postgres` instance:
9091
9192
>>> db.register_model(Foo)
9293
9394
That will plug your model into the :py:mod:`psycopg2` composite casting
94-
machinery, and you'll get instances of your model back from
95-
:py:meth:`~postgres.Postgres.all` and
96-
:py:meth:`~postgres.Postgres.one_or_zero`. If your query returns more than one
97-
column, you'll need to dereference the column containing the model just as with
98-
any other query:
95+
machinery, and you'll now get instances of your model back from
96+
:py:meth:`~postgres.Postgres.all` and :py:meth:`~postgres.Postgres.one_or_zero`
97+
when you cast your query results to the relevant type. If your query returns
98+
more than one column, you'll need to dereference the column containing the
99+
model just as with any other query:
99100
100101
>>> rec = db.one_or_zero("SELECT foo.*::foo, bar.* "
101102
... "FROM foo JOIN bar ON foo.bar = bar.bar "
@@ -105,9 +106,9 @@
105106
>>> rec.bar
106107
'blam'
107108
108-
As a special case, if your query only returns one column, and it's a
109-
:py:class:`~postgres.orm.Model`, then :py:meth:`~postgres.Postgres.all` and
110-
:py:meth:`~postgres.Postgres.one_or_zero` will do the dereferencing for you:
109+
As usual, if your query only returns one column, then
110+
:py:meth:`~postgres.Postgres.all` and :py:meth:`~postgres.Postgres.one_or_zero`
111+
will do the dereferencing for you:
111112
112113
>>> foo = db.one_or_zero("SELECT foo.*::foo FROM foo WHERE bar='blam'")
113114
>>> foo.bar
@@ -116,6 +117,8 @@
116117
['blam', 'whit']
117118
118119
120+
The Model Base Class
121+
--------------------
119122
120123
"""
121124
from __future__ import print_function, unicode_literals
@@ -151,7 +154,17 @@ def __str__(self):
151154
# =====
152155

153156
class Model(object):
154-
"""This is the base class for models under :py:mod:`postgres.orm`.
157+
"""
158+
159+
This is the base class for models in :py:mod:`postgres.orm`. Instances of
160+
subclasses of :py:class:`~postgres.orm.Model` will have an attribute for
161+
each field in the composite type for which the subclass is registered (for
162+
table and view types, these will be the columns of the table or view).
163+
These attributes are read-only. We don't update your database. You are
164+
expected to do that yourself in methods on your subclass. To keep instance
165+
attributes in sync after a database update, use the
166+
:py:meth:`~postgres.orm.Model.update_attributes` helper.
167+
155168
"""
156169

157170
typname = None # an entry in pg_type
@@ -173,16 +186,18 @@ def __setattr__(self, name, value):
173186
raise ReadOnly(name)
174187
return super(Model, self).__setattr__(name, value)
175188

176-
def update_local(self, **kw):
177-
"""Update self.__dict__ with kw.
189+
def update_attributes(self, **kw):
190+
"""Update instance attributes, according to :py:attr:`kw`.
178191
179192
:raises: :py:exc:`~postgres.orm.UnknownAttributes`
180193
181194
Call this when you update state in the database and you want to keep
182-
the attributes of your object in sync. Note that the only attributes we
183-
can update here are the ones that were given to us by the
195+
instance attributes in sync. Note that the only attributes we can
196+
update here are the ones that were given to us by the
184197
:py:mod:`psycopg2` composite caster machinery when we were first
185-
instantiated.
198+
instantiated. These will be the fields of the composite type for which
199+
we were registered, which will be column names for table and view
200+
types.
186201
187202
"""
188203
unknown = []

0 commit comments

Comments
 (0)