116116from psycopg2 .pool import ThreadedConnectionPool as ConnectionPool
117117
118118
119+ # A Helper
120+ # ========
121+
119122# Teach urlparse about postgres:// URLs.
120123if 'postgres' not in urlparse .uses_netloc :
121124 urlparse .uses_netloc .append ('postgres' )
@@ -137,6 +140,9 @@ def url_to_dsn(url):
137140 return dsn
138141
139142
143+ # The Main Event
144+ # ==============
145+
140146class Postgres (object ):
141147 """Interact with a `PostgreSQL <http://www.postgresql.org/>`_ datastore.
142148
@@ -164,7 +170,7 @@ def __init__(self, url, minconn=1, maxconn=10):
164170 self .pool = ConnectionPool ( minconn = minconn
165171 , maxconn = maxconn
166172 , dsn = dsn
167- , connection_factory = PostgresConnection
173+ , connection_factory = Connection
168174 )
169175
170176 def execute (self , * a , ** kw ):
@@ -194,7 +200,7 @@ def get_cursor(self, *a, **kw):
194200 upon both successful and exceptional executions against the cursor.
195201
196202 """
197- return PostgresCursorContextManager (self .pool , * a , ** kw )
203+ return CursorContextManager (self .pool , * a , ** kw )
198204
199205 def get_transaction (self , * a , ** kw ):
200206 """Return a context manager wrapping a transactional cursor.
@@ -206,21 +212,21 @@ def get_transaction(self, *a, **kw):
206212 fine-grained control over the transaction.
207213
208214 """
209- return PostgresTransactionContextManager (self .pool , * a , ** kw )
215+ return TransactionContextManager (self .pool , * a , ** kw )
210216
211217 def get_connection (self ):
212- """Return a context manager wrapping a PostgresConnection .
218+ """Return a context manager wrapping a :py:class:`postgres.Connection` .
213219
214220 This manager turns autocommit off, and back on when you're done with
215221 the connection. The connection is rolled back on exit, so be sure to
216222 call commit as needed. The idea is that you'd use this when you want
217223 full fine-grained transaction control.
218224
219225 """
220- return PostgresConnectionContextManager (self .pool )
226+ return ConnectionContextManager (self .pool )
221227
222228
223- class PostgresConnection (psycopg2 .extensions .connection ):
229+ class Connection (psycopg2 .extensions .connection ):
224230 """This is a subclass of psycopg2.extensions.connection.
225231
226232 Changes:
@@ -246,81 +252,84 @@ def cursor(self, *a, **kw):
246252 return psycopg2 .extensions .connection .cursor (self , * a , ** kw )
247253
248254
249- class PostgresTransactionContextManager (object ):
250- """Instantiated once per db.get_transaction call.
255+ # Context Managers
256+ # ================
257+
258+ class CursorContextManager (object ):
259+ """Instantiated once per cursor-level db access.
251260 """
252261
253262 def __init__ (self , pool , * a , ** kw ):
254263 self .pool = pool
264+ self .a = a
265+ self .kw = kw
255266 self .conn = None
256267
257- def __enter__ (self , * a , ** kw ):
268+ def __enter__ (self ):
258269 """Get a connection from the pool.
259270 """
260271 self .conn = self .pool .getconn ()
261- self .conn .autocommit = False
262- return self .conn .cursor (* a , ** kw )
272+ cursor = self .conn .cursor ()
273+ try :
274+ cursor .execute (* self .a , ** self .kw )
275+ except :
276+ # If we get an exception from execute (like, the query fails:
277+ # pretty common), then the __exit__ clause is not triggered. We
278+ # trigger it ourselves to avoid draining the pool.
279+ self .__exit__ ()
280+ raise
281+ return cursor
263282
264283 def __exit__ (self , * exc_info ):
265284 """Put our connection back in the pool.
266285 """
267- if exc_info == (None , None , None ):
268- self .conn .commit ()
269- else :
270- self .conn .rollback ()
271- self .conn .autocommit = True
272286 self .pool .putconn (self .conn )
273287
274288
275- class PostgresConnectionContextManager (object ):
276- """Instantiated once per db.get_connection call.
289+ class TransactionContextManager (object ):
290+ """Instantiated once per db.get_transaction call.
277291 """
278292
279293 def __init__ (self , pool , * a , ** kw ):
280294 self .pool = pool
281295 self .conn = None
282296
283- def __enter__ (self ):
297+ def __enter__ (self , * a , ** kw ):
284298 """Get a connection from the pool.
285299 """
286300 self .conn = self .pool .getconn ()
287301 self .conn .autocommit = False
288- return self .conn
302+ return self .conn . cursor ( * a , ** kw )
289303
290304 def __exit__ (self , * exc_info ):
291305 """Put our connection back in the pool.
292306 """
293- self .conn .rollback ()
307+ if exc_info == (None , None , None ):
308+ self .conn .commit ()
309+ else :
310+ self .conn .rollback ()
294311 self .conn .autocommit = True
295312 self .pool .putconn (self .conn )
296313
297314
298- class PostgresCursorContextManager (object ):
299- """Instantiated once per cursor-level db access .
315+ class ConnectionContextManager (object ):
316+ """Instantiated once per db.get_connection call .
300317 """
301318
302319 def __init__ (self , pool , * a , ** kw ):
303320 self .pool = pool
304- self .a = a
305- self .kw = kw
306321 self .conn = None
307322
308323 def __enter__ (self ):
309324 """Get a connection from the pool.
310325 """
311326 self .conn = self .pool .getconn ()
312- cursor = self .conn .cursor ()
313- try :
314- cursor .execute (* self .a , ** self .kw )
315- except :
316- # If we get an exception from execute (like, the query fails:
317- # pretty common), then the __exit__ clause is not triggered. We
318- # trigger it ourselves to avoid draining the pool.
319- self .__exit__ ()
320- raise
321- return cursor
327+ self .conn .autocommit = False
328+ return self .conn
322329
323330 def __exit__ (self , * exc_info ):
324331 """Put our connection back in the pool.
325332 """
333+ self .conn .rollback ()
334+ self .conn .autocommit = True
326335 self .pool .putconn (self .conn )
0 commit comments