Skip to content

Commit 73358da

Browse files
author
James William Pye
committed
Add a gotchas file documenting some of the more subtle issues.
1 parent fa1fe8d commit 73358da

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

doc/gotchas.txt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
py-postgresql gotchas
2+
=====================
3+
4+
It is recognized that decisions were made that may not always be ideal for a
5+
given user. In order to highlight those potential issues and hopefully bring
6+
some sense into a confusing situation, this document was drawn.
7+
8+
Cursors are not usable after transaction commits or aborts
9+
----------------------------------------------------------
10+
11+
`postgresql.driver` uses protocol level cursors. When a cursor is bound, there
12+
is no way for the driver to state that the cursor should be held via the
13+
protocol. This causes two potentially unfortunate things:
14+
15+
- In auto-commit mode, the entire cursor is read.
16+
- When a transaction closes, all cursors created become unusable.
17+
18+
Prepared statements, in contrast, are not automatically closed.
19+
20+
21+
client_encoding and TimeZone GUCs should not be altered
22+
-------------------------------------------------------
23+
24+
`postgresql.driver`'s cursor implementation reads a fixed set of rows when it
25+
queries the server for more. In order to optimized some situations, the driver
26+
will send a request for more data, but makes no attempt to wait and process the
27+
data as it is not yet needed. When the user comes back to read more data from
28+
the cursor, it will then look at this new data. The problem being, if the
29+
`client_encoding` or the `TimeZone` was switched, it may use the wrong codec and
30+
tzinfo to transform the wire data into higher level Python objects.
31+
32+
To avoid this problem from ever happening, set the `TimeZone` or
33+
`client_encoding` early. Furthermore, it is probably best to never change the
34+
`client_encoding` as the driver automatically makes the necessary tranformation
35+
to Python strings.
36+
37+
38+
The user and password is correct, but does it not work when using `postgresql.driver`
39+
-------------------------------------------------------------------------------------
40+
41+
This issue likely comes from the possibility that the information sent to the
42+
server early in the negotiation phase may not be in an encoding that is
43+
consistent with the server's encoding.
44+
45+
One problem is that PostgreSQL does not provide the client with the server
46+
encoding early enough in the negotiation phase, and, therefore, is unable to
47+
process the password data in a way that is consistent with the server's
48+
expectations.
49+
50+
Another problem is that PostgreSQL takes much of the data in the startup message
51+
as-is, so a decision about the best way to encode parameters is difficult.
52+
53+
The easy way to avoid *most* issues with this problem is to initialize the
54+
database in the `utf-8` encoding. The driver defaults the expected server
55+
encoding to `utf-8`. However, this can be overridden by creating the `Connector`
56+
with a `server_encoding` parameter. Setting `server_encoding` to the proper
57+
value of the target server will allow the driver to properly encode *some* of
58+
the parameters. Also, any GUC parameters passed via the `settings` parameter
59+
should use typed objects when possible to hint that the server encoding should
60+
not be used on that parameter.

0 commit comments

Comments
 (0)