3535 >>> db.fetchone("SELECT * FROM foo WHERE bar='blam'")
3636 None
3737
38- Work with a cursor directly:
38+
39+ Context Managers
40+ ++++++++++++++++
41+
42+ Eighty percent of your database usage should be covered by the simple API
43+ above. For the other 20%, :py:mod:`postgres` provides context managers for
44+ working at increasingly lower levels of abstraction. The lowest level of
45+ abstraction in :py:mod:`postgres` is a :py:mod:`psycopg2` connection pool that
46+ we configure and manage for you. Everything in :py:mod:`postgres`, both the
47+ simple API and the context managers, uses this connection pool.
48+
49+ Here's how to work directly with a `psycogpg2 cursor
50+ <http://initd.org/psycopg/docs/cursor.html>`_ while still taking advantage of
51+ connection pooling:
3952
4053 >>> with db.get_cursor('SELECT * FROM foo ORDER BY bar') as cursor:
4154 ... results = cursor.fetchall()
4255
56+ A cursor you get from :py:func:`~postgres.Postgres.get_cursor` has
57+ ``autocommit`` turned on for its connection, so every call you make using such
58+ a cursor will be isolated in a separate transaction. Need to include multiple
59+ calls in a single transaction? Use the
60+ :py:func:`~postgres.Postgres.get_transaction` context manager:
61+
62+ >>> with db.get_transaction() as txn:
63+ ... txn.execute("INSERT INTO foo VALUES ('blam')")
64+ ... txn.execute("SELECT * FROM foo ORDER BY bar")
65+ ... txn.fetchall()
66+ [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]
67+ ...
68+ ... db.fetchall("SELECT * FROM foo ORDER BY bar")
69+ [{"bar": "baz"}, {"bar": "buz"}]
70+ ...
71+ ... db.fetchall("SELECT * FROM foo ORDER BY bar")
72+ [{"bar": "baz"}, {"bar": "blam"}, {"bar": "buz"}]
73+
74+ The :py:func:`~postgres.Postgres.get_transaction` manager gives you a cursor
75+ with ``autocommit`` turned off on its connection. If the block under management
76+ raises, the connection is rolled back. Otherwise it's committed. Use this when
77+ you want a series of statements to be part of one transaction, but you don't
78+ need fine-grained control over the transaction. For fine-grained control, use
79+ :py:func:`~postgres.Postgres.get_connection` to get a connection straight from
80+ the connection pool:
81+
82+ >>> with db.get_connection() as connection:
83+ ... cursor = connection.cursor()
84+ ... cursor.execute('SELECT * FROM foo ORDER BY bar')
85+ ... cursor.fetchall()
86+ [{"bar": "baz"}, {"bar": "buz"}]
87+
88+ A connection gotten in this way will have ``autocommit`` turned off, and it'll
89+ never be implicitly committed otherwise. It'll actually be rolled back when
90+ you're done with it, so it's up to you to explicitly commit as needed.
91+
4392
4493API
4594---
@@ -150,15 +199,23 @@ def get_cursor(self, *a, **kw):
150199
151200 def get_transaction (self , * a , ** kw ):
152201 """Return a context manager wrapping a transactional cursor.
202+
203+ This manager returns a cursor with autocommit turned off on its
204+ connection. If the block under management raises then the connection is
205+ rolled back. Otherwise it's committed. Use this when you want a series
206+ of statements to be part of one transaction, but you don't need
207+ fine-grained control over the transaction.
208+
153209 """
154210 return PostgresTransactionContextManager (self .pool , * a , ** kw )
155211
156212 def get_connection (self ):
157213 """Return a context manager wrapping a PostgresConnection.
158214
159- The manager turns autocommit off for you and then turns it on again
160- when you're done with it. Use this when you need fine-grained
161- transaction control.
215+ This manager turns autocommit off, and back on when you're done with
216+ the connection. The connection is rolled back on exit, so be sure to
217+ call commit as needed. The idea is that you'd use this when you want
218+ full fine-grained transaction control.
162219
163220 """
164221 return PostgresConnectionContextManager (self .pool )
@@ -192,13 +249,6 @@ def cursor(self, *a, **kw):
192249
193250class PostgresTransactionContextManager (object ):
194251 """Instantiated once per db.get_transaction call.
195-
196- This manager gives you a cursor with autocommit turned off on its
197- connection. If the block under management raises then the connection is
198- rolled back. Otherwise it's committed. Use this when you want a series of
199- statements to be part of one transaction, but you don't need fine-grained
200- control over the transaction.
201-
202252 """
203253
204254 def __init__ (self , pool , * a , ** kw ):
@@ -225,12 +275,6 @@ def __exit__(self, *exc_info):
225275
226276class PostgresConnectionContextManager (object ):
227277 """Instantiated once per db.get_connection call.
228-
229- This manager turns autocommit off, and back on when you're done with it.
230- The connection is rolled back on exit, so be sure to call commit as needed.
231- The idea is that you'd use this when you want full fine-grained transaction
232- control.
233-
234278 """
235279
236280 def __init__ (self , pool , * a , ** kw ):
0 commit comments