Skip to content

Commit ff5d647

Browse files
author
James William Pye
committed
Get rid of data_files.
* Convert documentation into Python modules with a single doc-string. * Later, the same will be done package release data.
1 parent 21932ca commit ff5d647

10 files changed

Lines changed: 409 additions & 341 deletions

File tree

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
1-
import os.path
2-
# oh noes, not egg safe
3-
filename = os.path.join(os.path.dirname(__file__), 'index.txt')
4-
__doc__ = open(filename).read()
1+
##
2+
# copyright 2009, James William Pye
3+
# http://python.projects.postgresql.org
4+
##
5+
"""
6+
Contents:
7+
8+
Index
9+
`postgresql.documentation.index`
10+
11+
Driver Basics
12+
`postgresql.documentation.driver_basics`
13+
14+
Gotchas
15+
`postgresql.documentation.gotchas`
16+
"""
517
__docformat__ = 'reStructured Text'
18+
19+
# -m rejects this, so make the .index module the, well, index.
20+
if __name__ == '__main__':
21+
import sys
22+
if (sys.argv + [None])[1] == 'dump':
23+
sys.stdout.write(__doc__)
24+
else:
25+
try:
26+
help(__package__)
27+
except NameError:
28+
help(__name__)

postgresql/documentation/_default_.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

postgresql/documentation/driver_basics.py

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
##
2+
# copyright 2009, James William Pye
3+
# http://python.projects.postgresql.org
4+
##
5+
"""
6+
`postgresql.driver`
7+
===================
8+
9+
The `postgresql.driver` implements PG-API using PQ version 3.0 to connect to
10+
PostgreSQL servers. It makes use of the protocol's extended features to provide
11+
binary datatype transmission and protocol level prepared statements.
12+
13+
Connecting
14+
----------
15+
16+
Connecting to PostgreSQL using `postgresql.driver` is very simple::
17+
18+
>>> import postgresql.driver as pg_driver
19+
>>> pg_con = pg_driver.connect(user = 'usename', password = 'secret', host = 'localhost', port = 5432)
20+
21+
It's that easy.
22+
23+
NOTE: `connect` will *not* inherit parameters from the environment as
24+
libpq-based drivers do. The `postgresql.documentation.driver_details` discusses
25+
means of gathering standard client parameters.
26+
27+
Keyword parameters accepted by `connect`:
28+
29+
user
30+
The user to connect as.
31+
password
32+
The user's password.
33+
database
34+
The database to connect to. (PostgreSQL defaults it to `user`)
35+
host
36+
The hostname or IP address to connect to.
37+
port
38+
The port on the host to connect to.
39+
settings
40+
A dictionary or key-value pair sequence stating the parameters to give to the
41+
database. These settings are included in the startup packet.
42+
43+
connect_timeout
44+
Amount of time to wait for a connection to be made. (in seconds)
45+
Raises `postgresql.exceptions.ConnectionTimeoutError` when triggered.
46+
server_encoding
47+
Hint given to the driver to properly encode password data and some information
48+
in the startup packet.
49+
This should only be used in cases where connections cannot be made due to
50+
authentication failures that occur while using known-correct credentials.
51+
52+
sslmode
53+
How do to decide whether or not to use SSL:
54+
'disallow'
55+
Don't allow SSL connections.
56+
'allow'
57+
Try without SSL, but if that doesn't work, try with.
58+
'prefer'
59+
Try SSL first, then without.
60+
'require'
61+
62+
sslcrtfile
63+
Certificate file path given to `ssl.wrap_socket`.
64+
sslkeyfile
65+
Key file path given to `ssl.wrap_socket`.
66+
sslrootcrtfile
67+
Root certificate file path given to `ssl.wrap_socket`
68+
sslrootcrlfile
69+
Revocation list file path. [Throws a NotSupportedWarning]
70+
71+
From here on `db` will be assumed to exist and serve as the documentation's
72+
`postresql.api.Connection` instance.
73+
74+
Querying
75+
--------
76+
77+
Querying PostgreSQL is very easy. A statement object is created, a
78+
`PreparedStatement` instance, using the `prepare` method on the connection
79+
object::
80+
81+
>>> my_statement = db.prepare("SELECT 'hello, world!'")
82+
83+
This creates a bound statement object, so it's only usable on the `db`
84+
connection. While this may seem to be a trifle for some situations, it's very
85+
handy to be able to pass around the statement object without having to explicitly
86+
carry the connection object with it.
87+
88+
Now, to execute it::
89+
90+
>>> my_results = my_statement()
91+
92+
Just like executing a function. In this case, invoking `my_statement` will return a
93+
`Cursor` object to the result set.
94+
95+
NOTE: Don't confuse PG-API cursors with DB-API cursors. PG-API cursors are SQL
96+
cursors and don't contain methods for executing more queries within the cursor.
97+
98+
Cursor objects have a couple ways to read data from them:
99+
100+
``next(my_results)``
101+
This fetches the next row in the cursor object. Cursors support the iterator
102+
protocol, you can just as easily:
103+
104+
``for nextrow in my_results:``
105+
This will, of course, get the ``nextrow`` in the cursor, ``my_results``, until
106+
the cursor is exhausted. This and the former way of reading rows use the same
107+
method, ``__next__``, which is part of the Iterator ABC.
108+
109+
``my_results.read(5)``
110+
This method name is borrowed from `file` objects, and are semantically
111+
similar. However, this being a cursor, rows are returned instead of bytes or
112+
characters. In this case, five rows are requested, but certainly only one will
113+
come back: ``[('hello, world!',)]``. When the number of rows returned is less
114+
then the number requested, it means that cursor has been exhausted, and there
115+
are no more rows to be read.
116+
117+
Cursors have other methods, but not for reading more tuples. These other methods
118+
will be discuessed later.
119+
120+
As cursors have a couple methods for reading tuples, queries a few methods for
121+
executing the prepared statement:
122+
123+
``__call__(...)``
124+
As shown before, statement objects can be simply invoked like a function to get a
125+
cursor to the statement's results.
126+
127+
``first(...)``
128+
For simple queries, a cursor object can be a bit tiresome to get data from,
129+
consider the data contained in ``my_results``, 'hello world!'. To get at this
130+
data directly from the ``__call__(...)`` method, it looks something like::
131+
132+
>>> my_statement().read()[0][0]
133+
134+
While it's certainly easy to understand, it can be quite cumbersome and
135+
perhaps even error prone for more complicated queries returing single values.
136+
137+
To simplify access to simple data, the ``first`` method will simply return
138+
the "first" of the result set.
139+
140+
The first value: When there is a single row with a single column, ``first()``
141+
will return the contents of that cell.
142+
143+
The first row: When there is a single row with multiple columns, ``first()``
144+
will return that row.
145+
146+
The first column: When there is a single column with multiple rows,
147+
``first()`` will return that column as a sequence.
148+
149+
The first row count: When DML--for instance, an INSERT-statement--is executed,
150+
``first()`` will return the row count returned by the statement as an integer.
151+
152+
The result set created by the statement determines what is actually returned.
153+
Naturally, a statement used with ``first()`` should be crafted with these
154+
rules in mind.
155+
156+
Statement objects can take parameters. To do this, the statement must be defined using
157+
PostgreSQL's positional parameter notation. ``$1``, ``$2``, ``$3``, etc. If the
158+
statement object ``my_statement`` were to be re-written to take a parameter, it would be
159+
done simply::
160+
161+
>>> my_statement = db.prepare("SELECT $1")
162+
163+
And, re-create the ``my_cursor``::
164+
165+
>>> my_cursor = my_statement('hello, world!')
166+
167+
It's that easy. And using ``first()``::
168+
169+
>>> 'hello, world!' == my_statement.first('hello, world!')
170+
True
171+
172+
Inserting
173+
---------
174+
175+
Copying
176+
-------
177+
178+
Transacting
179+
-----------
180+
181+
Setting
182+
-------
183+
"""
184+
185+
__docformat__ = 'reStructured Text'
186+
if __name__ == '__main__':
187+
import sys
188+
if (sys.argv + [None])[1] == 'dump':
189+
sys.stdout.write(__doc__)
190+
else:
191+
try:
192+
help(__package__ + '.driver_basics')
193+
except NameError:
194+
help(__name__)

0 commit comments

Comments
 (0)