86
86
you. Everything in :py:mod:`postgres`, both the simple API and the context
87
87
managers, uses this connection pool.
88
88
89
- Use the :py:func:`~postgres.Postgres.get_transaction ` context manager to work
89
+ Use the :py:func:`~postgres.Postgres.get_cursor ` context manager to work
90
90
directly with a :py:mod:`psycogpg2` `cursor
91
91
<http://initd.org/psycopg/docs/cursor.html>`_ while still taking advantage of
92
92
connection pooling and automatic transaction management:
93
93
94
- >>> with db.get_transaction () as txn :
95
- ... txn .execute("INSERT INTO foo VALUES ('blam')")
96
- ... txn .execute("SELECT * FROM foo ORDER BY bar")
97
- ... txn .fetchall()
94
+ >>> with db.get_cursor () as cursor :
95
+ ... cursor .execute("INSERT INTO foo VALUES ('blam')")
96
+ ... cursor .execute("SELECT * FROM foo ORDER BY bar")
97
+ ... cursor .fetchall()
98
98
...
99
99
[Record(bar='bit', baz=537), Record(bar='blam', baz=None), Record(bar='buz', baz=42)]
100
100
101
101
Note that other calls won't see the changes on your transaction until the end
102
102
of your code block, when the context manager commits the transaction for you::
103
103
104
104
>>> db.run("DELETE FROM foo WHERE bar='blam'")
105
- >>> with db.get_transaction () as txn :
106
- ... txn .execute("INSERT INTO foo VALUES ('blam')")
105
+ >>> with db.get_cursor () as cursor :
106
+ ... cursor .execute("INSERT INTO foo VALUES ('blam')")
107
107
... db.all("SELECT * FROM foo ORDER BY bar")
108
108
...
109
109
[Record(bar='bit', baz=537), Record(bar='buz', baz=42)]
110
110
>>> db.all("SELECT * FROM foo ORDER BY bar")
111
111
[Record(bar='bit', baz=537), Record(bar='blam', baz=None), Record(bar='buz', baz=42)]
112
112
113
- The :py:func:`~postgres.Postgres.get_transaction` manager gives you a cursor
114
- with :py:attr:`autocommit` turned off on its connection. If the block under
115
- management raises an exception, the connection is rolled back. Otherwise it's
116
- committed. Use this when you want a series of statements to be part of one
117
- transaction, but you don't need fine-grained control over the transaction. For
118
- fine-grained control, use :py:func:`~postgres.Postgres.get_connection` to get a
119
- connection straight from the connection pool:
113
+ The :py:func:`~postgres.Postgres.get_cursor` method gives you a context manager
114
+ that wraps a cursor. It has :py:attr:`autocommit` turned off on its connection.
115
+ If the block under management raises an exception, the connection is rolled
116
+ back. Otherwise it's committed. Use this when you want a series of statements
117
+ to be part of one transaction, but you don't need fine-grained control over the
118
+ transaction. For fine-grained control, use
119
+ :py:func:`~postgres.Postgres.get_connection` to get a connection straight from
120
+ the connection pool:
120
121
121
122
>>> db.run("DELETE FROM foo WHERE bar='blam'")
122
123
>>> with db.get_connection() as connection:
@@ -295,7 +296,7 @@ class Postgres(object):
295
296
you set here, you can override that default on a per-call basis by passing
296
297
:py:attr:`record_type` or :py:attr:`cursor_factory` to
297
298
:py:meth:`~postgres.Postgres.one`, :py:meth:`~postgres.Postgres.all`, and
298
- :py:meth:`~postgres.Postgres.get_transaction `.
299
+ :py:meth:`~postgres.Postgres.get_cursor `.
299
300
300
301
The names in our simple API, :py:meth:`~postgres.Postgres.run`,
301
302
:py:meth:`~postgres.Postgres.one`, and :py:meth:`~postgres.Postgres.all`,
@@ -351,10 +352,8 @@ def run(self, sql, parameters=None, *a, **kw):
351
352
:param string sql: the SQL statement to execute
352
353
:param parameters: the bind parameters for the SQL statement
353
354
:type parameters: dict or tuple
354
- :param a: passed through to
355
- :py:meth:`~postgres.Postgres.get_transaction`
356
- :param kw: passed through to
357
- :py:meth:`~postgres.Postgres.get_transaction`
355
+ :param a: passed through to :py:meth:`~postgres.Postgres.get_cursor`
356
+ :param kw: passed through to :py:meth:`~postgres.Postgres.get_cursor`
358
357
:returns: :py:const:`None`
359
358
360
359
>>> db.run("DROP TABLE IF EXISTS foo CASCADE")
@@ -363,8 +362,8 @@ def run(self, sql, parameters=None, *a, **kw):
363
362
>>> db.run("INSERT INTO foo VALUES ('bit', 537)")
364
363
365
364
"""
366
- with self .get_transaction (* a , ** kw ) as txn :
367
- txn .execute (sql , parameters )
365
+ with self .get_cursor (* a , ** kw ) as cursor :
366
+ cursor .execute (sql , parameters )
368
367
369
368
370
369
def one (self , sql , parameters = None , record_type = None , default = None , \
@@ -378,9 +377,9 @@ def one(self, sql, parameters=None, record_type=None, default=None, \
378
377
:type record_type: type or string
379
378
:param default: the value to return if no results are found
380
379
:param a: passed through to
381
- :py:meth:`~postgres.Postgres.get_transaction `
380
+ :py:meth:`~postgres.Postgres.get_cursor `
382
381
:param kw: passed through to
383
- :py:meth:`~postgres.Postgres.get_transaction `
382
+ :py:meth:`~postgres.Postgres.get_cursor `
384
383
:returns: a single record or value or the value of the
385
384
:py:attr:`default` argument
386
385
:raises: :py:exc:`~postgres.TooFew` or :py:exc:`~postgres.TooMany`
@@ -481,9 +480,9 @@ def all(self, sql, parameters=None, record_type=None, *a, **kw):
481
480
:param record_type: the type of record to return
482
481
:type record_type: type or string
483
482
:param a: passed through to
484
- :py:meth:`~postgres.Postgres.get_transaction `
483
+ :py:meth:`~postgres.Postgres.get_cursor `
485
484
:param kw: passed through to
486
- :py:meth:`~postgres.Postgres.get_transaction `
485
+ :py:meth:`~postgres.Postgres.get_cursor `
487
486
:returns: :py:class:`list` of records or :py:class:`list` of single
488
487
values
489
488
@@ -527,9 +526,9 @@ def all(self, sql, parameters=None, record_type=None, *a, **kw):
527
526
[537, 42]
528
527
529
528
"""
530
- with self .get_transaction (record_type = record_type , * a , ** kw ) as txn :
531
- txn .execute (sql , parameters )
532
- recs = txn .fetchall ()
529
+ with self .get_cursor (record_type = record_type , * a , ** kw ) as cursor :
530
+ cursor .execute (sql , parameters )
531
+ recs = cursor .fetchall ()
533
532
if recs and len (recs [0 ]) == 1 : # dereference
534
533
if hasattr (recs [0 ], 'values' ): # mapping
535
534
recs = [list (rec .values ())[0 ] for rec in recs ]
@@ -545,56 +544,57 @@ def _some(self, sql, parameters, lo, hi, record_type, *a, **kw):
545
544
# had those two methods. Help yourself to _some now that you've found
546
545
# it. :^)
547
546
548
- with self .get_transaction (record_type = record_type , * a , ** kw ) as txn :
549
- txn .execute (sql , parameters )
547
+ with self .get_cursor (record_type = record_type , * a , ** kw ) as cursor :
548
+ cursor .execute (sql , parameters )
550
549
551
- if txn .rowcount < lo :
552
- raise TooFew (txn .rowcount , lo , hi )
553
- elif txn .rowcount > hi :
554
- raise TooMany (txn .rowcount , lo , hi )
550
+ if cursor .rowcount < lo :
551
+ raise TooFew (cursor .rowcount , lo , hi )
552
+ elif cursor .rowcount > hi :
553
+ raise TooMany (cursor .rowcount , lo , hi )
555
554
556
- return txn .fetchone ()
555
+ return cursor .fetchone ()
557
556
558
557
559
- def get_transaction (self , * a , ** kw ):
560
- """Return a :py:class:`~postgres.TransactionContextManager ` that uses
558
+ def get_cursor (self , * a , ** kw ):
559
+ """Return a :py:class:`~postgres.CursorContextManager ` that uses
561
560
our connection pool.
562
561
562
+ >>> with db.get_cursor() as cursor:
563
+ ... cursor.execute("SELECT * FROM foo")
564
+ ... cursor.fetchall()
565
+ ...
566
+ [Record(bar='buz', baz=42), Record(bar='bit', baz=537)]
567
+
563
568
This gets you a cursor with :py:attr:`autocommit` turned off on its
564
569
connection. If your code block inside the :py:obj:`with` statement
565
570
raises an exception, the transaction will be rolled back. Otherwise,
566
571
it'll be committed. The context manager closes the cursor when the
567
- block ends.
572
+ block ends, resets :py:attr:`autocommit` to off on the connection, and
573
+ puts the connection back in the pool.
568
574
569
575
Use this when you want a series of statements to be part of one
570
576
transaction, but you don't need fine-grained control over the
571
577
transaction.
572
578
573
- >>> with db.get_transaction() as txn:
574
- ... txn.execute("SELECT * FROM foo")
575
- ... txn.fetchall()
576
- ...
577
- [Record(bar='buz', baz=42), Record(bar='bit', baz=537)]
578
-
579
579
"""
580
- return TransactionContextManager (self .pool , * a , ** kw )
580
+ return CursorContextManager (self .pool , * a , ** kw )
581
581
582
582
583
583
def get_connection (self ):
584
584
"""Return a :py:class:`~postgres.ConnectionContextManager` that uses
585
585
our connection pool.
586
586
587
- Use this when you want to take advantage of connection pooling, but
588
- otherwise need full control, for example, to do complex things with
589
- transactions.
590
-
591
587
>>> with db.get_connection() as connection:
592
588
... cursor = connection.cursor()
593
589
... cursor.execute("SELECT * FROM foo")
594
590
... cursor.fetchall()
595
591
...
596
592
[Record(bar='buz', baz=42), Record(bar='bit', baz=537)]
597
593
594
+ Use this when you want to take advantage of connection pooling, but
595
+ otherwise need full control, for example, to do complex things with
596
+ transactions.
597
+
598
598
"""
599
599
return ConnectionContextManager (self .pool )
600
600
@@ -669,13 +669,13 @@ def unregister_model(self, ModelSubclass):
669
669
# Context Managers
670
670
# ================
671
671
672
- class TransactionContextManager (object ):
673
- """Instantiated once per :py:func:`~postgres.Postgres.get_transaction `
672
+ class CursorContextManager (object ):
673
+ """Instantiated once per :py:func:`~postgres.Postgres.get_cursor `
674
674
call.
675
675
676
676
:param pool: a :py:class:`psycopg2.pool.*ConnectionPool`
677
677
678
- The return value of :py:func:`TransactionContextManager .__enter__` is a
678
+ The return value of :py:func:`CursorContextManager .__enter__` is a
679
679
:py:mod:`psycopg2` cursor. Any positional and keyword arguments to our
680
680
constructor are passed through to the cursor constructor. If you pass
681
681
:py:attr:`record_type` as a keyword argument then we'll infer a
@@ -741,7 +741,7 @@ def compute_cursor_factory(self, **kw):
741
741
# Pull record_type out of kw.
742
742
# ===========================
743
743
# If we leave it in psycopg2 will complain. Our internal calls to
744
- # get_transaction always have it but external use might not.
744
+ # get_cursor always have it but external use might not.
745
745
746
746
record_type = kw .pop ('record_type' , None )
747
747
0 commit comments