|
19 | 19 |
|
20 | 20 | .. note:: |
21 | 21 | PostgreSQL versions 8.1 and earlier do not support standard conforming |
22 | | - strings. A warning will be raised whenever a connection is established to a |
23 | | - server that does not support standard conforming strings. |
| 22 | + strings. A warning will be raised whenever a connection is established to a |
| 23 | + server that does not support standard conforming strings. |
24 | 24 |
|
25 | 25 | The following identifiers are regularly used as shorthands for significant |
26 | 26 | interface elements: |
|
153 | 153 | The driver, `postgresql.driver.default` provides a set of connectors for making |
154 | 154 | a connection: |
155 | 155 |
|
156 | | - ``driver.host`` |
| 156 | + ``postgresql.driver.default.host(...)`` |
157 | 157 | Provides a ``getaddrinfo()`` abstraction for establishing a connection. |
158 | 158 |
|
159 | | - ``driver.ip4`` |
| 159 | + ``postgresql.driver.default.ip4(...)`` |
160 | 160 | Connect to a single IPv4 addressed host. |
161 | 161 |
|
162 | | - ``driver.ip6`` |
| 162 | + ``postgresql.driver.default.ip6(...)`` |
163 | 163 | Connect to a single IPv6 addressed host. |
164 | 164 |
|
165 | | - ``driver.unix`` |
| 165 | + ``postgresql.driver.default.unix(...)`` |
166 | 166 | Connect to a single unix domain socket. |
167 | 167 |
|
168 | 168 | ``host`` is the usual connector used to establish a connection:: |
|
257 | 257 | Revocation list file path. [Currently not checked.] |
258 | 258 |
|
259 | 259 |
|
260 | | -Connection Failures |
261 | | -------------------- |
262 | | -
|
263 | | -If a connection cannot be established, a |
264 | | -`postgresql.exceptions.ClientCannotConnectError` will be raised. |
265 | | -
|
266 | | -This exception carries the cause of the failures. However, in situations |
267 | | -involving ``Host`` connectors and ``'prefer'`` or ``'allow'`` ``sslmode``'s, |
268 | | -multiple attempts may be made before the exception is thrown. Therefore, |
269 | | -multiple exception conditions may have contributed to the ultimate |
270 | | -failure of the connection, and reliance on ``__context__`` or ``__cause__`` to |
271 | | -provide this information is inappropriate. |
272 | | -
|
273 | | -
|
274 | 260 | Connections |
275 | 261 | =========== |
276 | 262 |
|
|
438 | 424 | Consider the data contained in ``c`` from above, 'hello world!'. To get at this |
439 | 425 | data directly from the ``__call__(...)`` method, it looks something like:: |
440 | 426 |
|
441 | | - >>> ps().read()[0][0] |
| 427 | + >>> ps()[0][0] |
442 | 428 |
|
443 | 429 | To simplify access to simple data, the ``first`` method will simply return |
444 | 430 | the "first" of the result set:: |
|
660 | 646 | appropriate encoding. |
661 | 647 |
|
662 | 648 |
|
| 649 | +COPY Statements |
| 650 | +--------------- |
| 651 | +
|
| 652 | +`postgresql.driver` transparently supports PostgreSQL's COPY command. To the |
| 653 | +user, COPY will act exactly like other statements that produce tuples; COPY |
| 654 | +tuples, however, are `bytes` objects. The only distinction in usability is that |
| 655 | +the COPY *should* be completed before other actions take place on the |
| 656 | +connection--this is important when a COPY is invoked via ``rows()`` or |
| 657 | +``chunks()``. |
| 658 | +
|
| 659 | +In situations where other actions are invoked during a ``COPY TO STDOUT``, the |
| 660 | +entire result set of the COPY will be read. However, no error will be raised so |
| 661 | +long as there is enough memory available, so it is *very* desirable to avoid |
| 662 | +doing other actions on the connection while a COPY is active. |
| 663 | +
|
| 664 | +In situations where other actions are invoked during a ``COPY FROM STDIN``, a |
| 665 | +COPY failure error will occur. The driver manages the connection state in such |
| 666 | +a way that will purposefully cause the error as the COPY was inappropriately |
| 667 | +interrupted. This not usually a problem as the ``load(...)`` method must |
| 668 | +complete the COPY command before returning. |
| 669 | +
|
| 670 | +Copy data is always transferred using ``bytes`` objects. Even in cases where the |
| 671 | +COPY is not in ``BINARY`` mode. Any needed encoding transformations *must* be |
| 672 | +made the caller. This is done to avoid any unnecessary overhead by default:: |
| 673 | +
|
| 674 | + >>> ps = db.prepare("COPY (SELECT i FROM generate_series(0, 99) AS g(i)) TO STDOUT") |
| 675 | + >>> r = ps() |
| 676 | + >>> len(r) |
| 677 | + 100 |
| 678 | + >>> r[0] |
| 679 | + b'0\n' |
| 680 | + >>> r[-1] |
| 681 | + b'99\n' |
| 682 | +
|
| 683 | +Of course, invoking a statement that way will ready the entire result-set into |
| 684 | +memory, which is not usually desirable for COPY. Using the ``chunks(...)`` |
| 685 | +iterator is the fastest way to move data:: |
| 686 | +
|
| 687 | + >>> ci = ps.chunks() |
| 688 | + >>> import sys |
| 689 | + >>> for rowset in ps.chunks(): |
| 690 | + ... sys.stdout.buffer.writelines(rowset) |
| 691 | + ... |
| 692 | + <Lots of Data> |
| 693 | +
|
| 694 | +``COPY FROM STDIN`` commands are supported via |
| 695 | +`postgresql.api.PreparedStatement.load`. Each invocation to ``load`` |
| 696 | +is a single invocation of COPY. ``load`` takes an iterable of COPY lines |
| 697 | +to send to the server:: |
| 698 | +
|
| 699 | + >>> db.execute(""" |
| 700 | + ... CREATE TABLE sample_copy ( |
| 701 | + ... sc_number int, |
| 702 | + ... sc_text text |
| 703 | + ... ); |
| 704 | + ... """) |
| 705 | + >>> copyin = db.prepare('COPY sample_copy FROM STDIN') |
| 706 | + >>> copyin.load([ |
| 707 | + ... b'123\tone twenty three\n', |
| 708 | + ... b'350\ttree fitty\n', |
| 709 | + ... ]) |
| 710 | +
|
| 711 | +The ``load()`` method is trained to identify chunk iterators so that direct |
| 712 | +transfers from a source database to a destination database could be |
| 713 | +made in a streaming fashion:: |
| 714 | +
|
| 715 | + >>> copyout = src.prepare('COPY atable TO STDOUT') |
| 716 | + >>> copyin = dst.prepare('COPY atable FROM STDIN') |
| 717 | + >>> copyin.load(copyout.chunks()) |
| 718 | +
|
| 719 | +
|
663 | 720 | Cursors |
664 | 721 | ======= |
665 | 722 |
|
|
801 | 858 | ... EXTRACT(years FROM AGE(employee_dob)) AS age |
802 | 859 | ... ORDER BY age ASC |
803 | 860 | ... """) |
804 | | - >>> snapshot = emps_by_age.declare() |
| 861 | + >>> c = emps_by_age.declare() |
805 | 862 | >>> # seek to the end, ``2`` works as well. |
806 | | - >>> snapshot.seek(0, 'FROM_END') |
| 863 | + >>> c.seek(0, 'FROM_END') |
807 | 864 | >>> # scroll back one, ``1`` works as well. |
808 | | - >>> snapshot.seek(-1, 'RELATIVE') |
| 865 | + >>> c.seek(-1, 'RELATIVE') |
809 | 866 | >>> # and back to the beginning again |
810 | | - >>> snapshot.seek(0) |
| 867 | + >>> c.seek(0) |
811 | 868 |
|
812 | 869 | Additionally, scrollable cursors support backward fetches by specifying the |
813 | 870 | direction keyword argument:: |
814 | 871 |
|
815 | | - >>> snapshot.seek(0, 2) |
816 | | - >>> snapshot.read(1, 'BACKWARD') |
| 872 | + >>> c.seek(0, 2) |
| 873 | + >>> c.read(1, 'BACKWARD') |
817 | 874 |
|
818 | 875 |
|
819 | 876 | Cursor Direction |
|
851 | 908 | >>> c.read(10, 'BACKWARD') == reverse_c.read(10, 'BACKWARD') |
852 | 909 |
|
853 | 910 |
|
854 | | -COPY |
855 | | -==== |
856 | | -
|
857 | | -`postgresql.driver` transparently supports PostgreSQL's COPY command. To the |
858 | | -user, COPY will act exactly like other statements that produce tuples; COPY |
859 | | -tuples, however, are `bytes` objects. The only distinction in usability is that |
860 | | -the COPY *should* be completed before other actions take place on the |
861 | | -connection--this is important when a COPY is invoked via ``rows()`` or |
862 | | -``chunks()``. |
863 | | -
|
864 | | -In situations where other actions are invoked during a ``COPY TO STDOUT``, the |
865 | | -entire result set of the COPY will be read. However, no error will be raised so |
866 | | -long as there is enough memory available, so it is *very* desirable to avoid |
867 | | -doing other actions on the connection while a COPY is active. |
868 | | -
|
869 | | -In situations where other actions are invoked during a ``COPY FROM STDIN``, a |
870 | | -COPY failure error will occur. The driver manages the connection state in such |
871 | | -a way that will purposefully cause the error as the COPY was inappropriately |
872 | | -interrupted. This not usually a problem as the ``load(...)`` method must |
873 | | -complete the COPY command before returning. |
874 | | -
|
875 | | -Copy data is always transferred using ``bytes`` objects. Even in cases where the |
876 | | -COPY is not in ``BINARY`` mode. Any needed encoding transformations *must* be |
877 | | -made the caller. This is done to avoid any unnecessary overhead by default. |
878 | | -
|
879 | | -``COPY FROM STDIN`` commands are supported via |
880 | | -`postgresql.api.PreparedStatement.load`. Each invocation to ``load`` |
881 | | -is a single invocation of COPY. ``load`` takes an iterable of COPY lines |
882 | | -to send to the server:: |
883 | | -
|
884 | | - >>> db.execute(""" |
885 | | - ... CREATE TABLE sample_copy ( |
886 | | - ... sc_number int, |
887 | | - ... sc_text text |
888 | | - ... ); |
889 | | - ... """) |
890 | | - >>> copyin = db.prepare('COPY sample_copy FROM STDIN') |
891 | | - >>> copyin.load([ |
892 | | - ... b'123\tone twenty three\n', |
893 | | - ... b'350\ttree fitty\n', |
894 | | - ... ]) |
895 | | -
|
896 | | -Copy cursors and the load interface was designed to be used together so that |
897 | | -direct transfers from a source database to a destination database could be |
898 | | -made in a streaming fashion:: |
899 | | -
|
900 | | - >>> copyout = src.prepare('COPY atable TO STDOUT') |
901 | | - >>> copyin = dst.prepare('COPY atable FROM STDIN') |
902 | | - >>> copyin.load(copyout.chunks()) |
903 | | -
|
904 | | -
|
905 | 911 | Rows |
906 | 912 | ==== |
907 | 913 |
|
|
1146 | 1152 | ... $body$; |
1147 | 1153 | ... """) |
1148 | 1154 | >>> srfcomposite = db.proc('srfcomposite()') |
1149 | | - >>> c = srfcomposite() |
1150 | | - >>> c |
1151 | | - <postgresql.driver.pq3.DeclaredCursor object> |
1152 | | - >>> c.read(1) |
1153 | | - [(900, 'sample text')] |
1154 | | - >>> r = c.read(1)[0] |
1155 | | - >>> r['i'], r['t'] |
| 1155 | + >>> r = srfcomposite() |
| 1156 | + >>> next(r) |
| 1157 | + (900, 'sample text') |
| 1158 | + >>> v = next(r) |
| 1159 | + >>> v['i'], v['t'] |
1156 | 1160 | (450, 'more sample text') |
1157 | 1161 |
|
1158 | 1162 |
|
|
1220 | 1224 | in a way that cannot be formed around single, sequential blocks of code. |
1221 | 1225 | Generally, using these methods require additional work to be performed by the |
1222 | 1226 | code that is managing the transaction. |
1223 | | -If usage of these direct, instructional methods is necessary, there is one |
1224 | | -important factor to keep in mind: |
1225 | | -
|
1226 | | - * If the database is in an error state when a block's commit() is executed, |
1227 | | - an implicit rollback will occur. The transaction object will simply follow |
1228 | | - instructions and issue the ``COMMIT`` statement, and it will succeed without |
1229 | | - exception. |
| 1227 | +If usage of these direct, instructional methods is necessary, it is important to |
| 1228 | +note that if the database is in an error state when a *transaction block's* |
| 1229 | +commit() is executed, an implicit rollback will occur. The transaction object |
| 1230 | +will simply follow instructions and issue the ``COMMIT`` statement, and it will |
| 1231 | +succeed without exception. |
1230 | 1232 |
|
1231 | 1233 |
|
1232 | 1234 | Error Control |
|
1325 | 1327 | Traceback (most recent call last): |
1326 | 1328 | ... |
1327 | 1329 | postgresql.exceptions.ActiveTransactionError: COMMIT PREPARED cannot run inside a transaction block |
| 1330 | + CAUSE: The prepared transaction was not prepared prior to the block's exit. |
1328 | 1331 | CODE: 25001 |
1329 | 1332 | SEVERITY: ERROR |
1330 | | - INTERFACE: The prepared transaction was not prepared prior to the block's exit. |
1331 | 1333 | LOCATION: File 'xact.c', line 2648, in PreventTransactionChain |
1332 | 1334 |
|
1333 | 1335 |
|
|
1360 | 1362 | postgresql.exceptions.UndefinedObjectError: ... |
1361 | 1363 |
|
1362 | 1364 | This allows recovery operations to identify the existence of the prepared |
1363 | | -transaction. Global transaction managers should trap this exception in order to |
1364 | | -identify how to proceed. |
| 1365 | +transaction. Transaction managers should trap this exception in order to |
| 1366 | +determine how to proceed. |
1365 | 1367 |
|
1366 | 1368 |
|
1367 | 1369 | Settings |
|
0 commit comments