From: SourceForge.net <no...@so...> - 2004-08-09 09:29:44
|
Bugs item #1005037, was opened at 2004-08-07 07:26 Message generated for change (Comment added) made by frankmillman You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=116528&aid=1005037&group_id=16528 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Frank Millman (frankmillman) Assigned to: Nobody/Anonymous (nobody) Summary: Problem with pgInt8 not defined Initial Comment: This is a copy of a message sent to comp.lang.python regarding a possible bug in pgPySQL. It is rather long, but I have reproduced it verbatim as any/all of it may be significant. Thanks. Below is the text of a message I was about to send in connection with an obscure problem. I have now almost got to the bottom of it, and am fairly confident that it is a bug in pyPgSQL. I hope this is the correct place to report such bugs. If not, please advise the correct forum. I have left the original message intact as it provides important information. At the bottom, I have recorded the new information that I have discovered. ------------------------------------------------------ ------------------------- Here is an obscure problem. I am not sure if I can explain the symptoms properly, but I will do my best. I have a Linux box (RH9) and an MSW box (W2K Pro) networked to each other. Both are running Python 2.3.3. Linux is the server. It is running PostgreSQL, which listens on port 5432. It is also running a socket server program that I have written using socket.socket(), listening on port 6543. I am using pyPgSQL to connect to the database. MSW is the client. From time to time it sends messages to my socket server. Messages are strings consisting of a single digit identifier, followed by a cPickle'd tuple containing various data fields. The client uses cPickle.dumps to prepare the string before sending, and the server uses cPickle.loads to unpickle it after receiving. Most times it works perfectly, but in one particular situation the server terminates with an error. The error is consistent - it always gives the same error resulting from the same message. However, I do not think it is caused by the message itself, as exactly the same message is sent in different circumstances without generating an error. The traceback is as follows - File "./chag_server.py", line 190, in ? dat = cPickle.loads(data[1:]) File "/usr/local/lib/python2.3/site- packages/pyPgSQL/libpq/__init__.py", line 43, in _I8 return PgInt8(value) NameError: ("global name 'PgInt8' is not defined", <function _I8 at 0x403a04c4>, ('17',)) The error occurs at the point of unpickling - I have moved this around, and it always fails at this point. A typical example of the tuple being unpickled is (2,'Ar',17,1) - it is all normal strings and integers. I have no idea why pyPgSQL is involved at all - I am certainly not invoking it directly. In fact the error comes from my server program, and that does not even import pyPgSQL. Here are the relevant lines from pyPgSQL/libpq/__init__.py - from libpq import * from libpq import __version__ HAVE_LONG_LONG_SUPPORT = dir().count('PgInt8') == 1 #-------------------------------------------------- -------------+ # Add support to pickle the following pyPgSQL objects: | # PgInt2, PgInt8, PgBoolean | #-------------------------------------------------- -------------+ def _B(value): return PgBoolean(value) def _I2(value): return PgInt2(value) def _I8(value): return PgInt8(value) Somehow pyPgSQL is responding to my unpickling command, and raising an error because PgInt8 is not defined. Here is another fact, which may provide a clue or may add confusion. If I run exactly the same program from the Linux box, using it as the client as well as the server, the error does not appear. I connect via the external IP address, not via 127.0.0.1, so I would have thought it would behave the same, but it does not. ------------------------------------------------------ ------------------------- Ok, here is the reason. I mentioned above that a typical tuple consists of (2,'Ar',17,1). I have found that under some circumstances the 3rd element is of type 'long' instead of type 'int', and this is what generates the error. Whether it is a long or an int is determined by pyPgSQL itself. It is a column value, where the column is of type 'serial', which means that PostgreSQL will generate a next number if the row is being inserted. If the row exists, the column value is returned along with all the other columns, and is returned as type int. If the row does not exist, I insert it, and then to retrieve the id generated, I have the following piece of code - cur = db.cursor() cur.execute("select currval('%s_%s_Seq')" % (tableid,columnid) ) rowid = cur.fetchone()[0] In this case, rowid contains the correct value, but is of type long. So this raises various questions - Why is PgInt8 not defined? Why does pyPgSQL affect my server program, which does not import any of pyPgSQL? Why does the error only occur when I connect from a remote machine? Now that I have identified the problem, I can work around it, so this has become a matter of correctness rather than a matter of urgency. Frank Millman ---------------------------------------------------------------------- >Comment By: Frank Millman (frankmillman) Date: 2004-08-09 09:29 Message: Logged In: YES user_id=1070042 Apologies - my diagnosis was not quite correct. What is actually happening is as follows. Refer to the lines where I retrieve the id generated, ending with "rowid = cur.fetchone()[0]" If this line is executed from a Linux machine, rowid's type is "long". If it is executed from a Windows machine, rowid's type is "PgInt8". This explains why the error only occurs when I connect from the Windows machine. Frank ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=116528&aid=1005037&group_id=16528 |