From: Mike C. F. <mcf...@ro...> - 2004-02-25 07:27:18
|
I've just recently upgraded to postgresql 7.4 on cygwin, and am now seeing some strange behaviour of PyPgSQL cursors. There were a number of changes to the semantics of cursor lifetimes in the 7.3 to 7.4 transition, so I'm wondering if they might be the source of the problems, and if so, if anyone has worked around them already. Basically the symptoms are that in a large application, I'm getting operational errors raised like that below (I've been unable to duplicate the effect in small test-scripts, unfortunately). The errors are consistently seen with certain tests. The code in question is using a single connection, creating temporary cursors for individual (sequentially occurring) operations. There's no threading going on. This is with the latest PyPgSQL: (self.conn.conn is: <Opened PgConnection at 013D19E0>) Traceback (most recent call last): File "p:\sharedinstall\pyPgSQL\PgSQL.py", line 3098, in execute self.res = self.conn.conn.query(_qstr % parms) OperationalError: ERROR: cursor "PgSQL_013CAD78" already exists I've been playing with adding a serial number to the name of the cursor, and it does appear as though the same cursor object is attempting to multiply-create itself during the query call (as opposed to a chance duplication of memory address causing two temporally disjoint cursors to share the same name). I'm thinking I'll have to regress to PostgreSQL 7.3 for now, but would love to hear if anyone has encountered and/or worked around the issue. Thoughts appreciated, Mike _______________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://members.rogers.com/mcfletch/ |
From: Mike C. F. <mcf...@ro...> - 2004-02-25 10:02:42
|
More details here. The error is occurring on the first call to cursor.execute in the process (and all subsequent calls), so not likely a matter of leftover cursors or cursors hanging around from previous calls within the process. First query is: DECLARE "PgSQL_01323DF01" CURSOR FOR SELECT tablename FROM pg_tables WHERE tablename !~ '^pg_' AND tablename !~ '^pga_'; setting noPostgresCursor true works around the effect (i.e. the queries work fine). (Note: the passed in query starts with "SELECT", the cursor class is adding the declare when noPostgresCursor is false). As to why I can't provoke the darned thing to show the same error with a script executing the same query, no clue. I'm assuming it's some weird effect of, for instance, not having a hard reference to a connection anywhere (though that fails in a different way in my tests), or some weird interaction with the apps logging DB connection (though that's not getting called in the test, and simulating it's existence with another connection doesn't affect anything), or bad karma left over from some previous life :) . For now I'll just set noPostgresCursor true and get back to real work, but I would still be very curious to see what others think might cause such an effect. Have fun, Mike Mike C. Fletcher wrote: ... > Traceback (most recent call last): > File "p:\sharedinstall\pyPgSQL\PgSQL.py", line 3098, in execute > self.res = self.conn.conn.query(_qstr % parms) > OperationalError: ERROR: cursor "PgSQL_013CAD78" already exists ... _______________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://members.rogers.com/mcfletch/ |
From: Mike C. F. <mcf...@ro...> - 2004-02-25 10:54:12
|
Found it. At some point I must have accidentally hit a delete key and out-dented a line in PgSQL.py while trying to track down a different error: if len(parms) == 1 and \ (type(parms[0]) in [DictType, ListType, TupleType] or \ isinstance(parms[0], PgResultSet)): parms = _quoteall(self.__unicodeConvert(parms[0])) self.res = self.conn.conn.query(_qstr % parms) else: parms = self.__unicodeConvert(parms) parms = tuple(map(_quote, self.__unicodeConvert(parms))); self.res = self.conn.conn.query(_qstr % parms) so the query wound up being executed twice if a request met a particular requirement, and once otherwise. The reason I couldn't reproduce the error in a script is that I was passing in the fully-expanded SQL queries in order to be sure I was executing exactly what was getting to the engine. Those would always take the "else" branch and thus only create the cursor once (and, incidentally, this explains the previously-seen problem of mysterious duplicate inserts which triggered the whole update to PostgreSQL 7.4 in the first place). Sigh. Two days gone for a stupid reformatting/random keypress error. I should beat myself about the head for that one. Sorry for bothering everyone with this. Night all, Mike _______________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://members.rogers.com/mcfletch/ |