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