繁体   English   中英

使用 psycopg2 与 PostgreSQL 的 Python 连接 - 为什么需要关闭并重新打开连接才能使代码正常工作?

[英]Python connections to PostgreSQL using psycopg2 - Why need to close & re-open connection for ensuing code to work?

我在使用psycopg2时遇到了一个谜:

  • 我的程序连接正常,并创建一个游标 OK
  • 此游标在“try ... except”结构中用于删除两个临时表(如果存在)
  • ('except' 逻辑对这两个都运行,因为这些表不存在。)
  • 但是,接下来的程序的其余部分在第一个“.execute()”处崩溃,因为它无法使用它似乎从该连接创建的新游标。
  • 如果我关闭连接并重新打开它(或创建并使用第二个连接),随后的逻辑运行良好。
  • (如果我注释掉“try ...except”两个构造,它运行良好,可以理解。)

下面是程序代码:

import psycopg2             # PostgreSQL module - need to install.  See https://www.psycopg.org/docs/

lcConnectionString = "...obfuscated..."

loConnection = psycopg2.connect(lcConnectionString)
print(f"loConnection after '.connect()' is: {loConnection}")

loCursor = loConnection.cursor()
print(f"loCursor is {loCursor}")

try:
    loCursor.execute("drop table TmpJobs")
    print("Dropped TmpJobs table")
except Exception as exc:
    print("Did not need to drop TmpJobs table table")

try:
    loCursor.execute("drop table TmpSubset")
    print("Dropped TmpSubset table")
except Exception as exc:
    print("Did not need to drop TmpSubset table")

print(f"loConnection after 'exceptions' is: {loConnection}")
print(f"loCursor after 'exceptions' is {loCursor}")

# The rest of the program runs fine if close and reopen the connection. But crashes if don't.
llCloseAndReopen = False            # Testing: True / False
if llCloseAndReopen:
   loConnection.close()
   print(f"loConnection after '.close()' is: {loConnection}")
   loConnection = loCursor = None
   loConnection = psycopg2.connect(lcConnectionString)
   print(f"loConnection after 're-connect' is: {loConnection}")

print("\n-----------------------------------------\nSelecting from Jobs into subset result...")
loCursor2 = loConnection.cursor()
print(f"loCursor2 (just created): {loCursor2}")

loCursor2.execute(f"create temporary table TmpSubset as select * from Jobs where RowID % 100 = 0")

loCursor2.execute(f"select * from TmpSubset")
loResult = loCursor2.fetchall() 
print(f"{len(loCursor2.description)} columns in Subset result")
lnRowCount = 0
for Row in loResult:
    lnRowCount += 1
    print(f"{lnRowCount}: {Row[0]}, {Row[1]}, {Row[2]}, {Row[3]}")
print(f"{lnRowCount} rows in Subset result")

如果连接没有关闭并重新打开,则该行抛出异常:

loCursor2.execute(f"create temporary table TmpSubset as select * from Jobs where RowID % 100 = 0")

根据要求于 11 月 19 日添加:这是 Visual Studio 2019“输出”窗口的最后一部分,显示了最后的打印语句、异常消息和堆栈跟踪:

Did not need to drop TmpSubset table
loConnection after 'exceptions' is: <connection object at 0x0579D878; dsn: 'user= ...obfuscated... host=localhost', closed: 0>
loCursor after 'exceptions' is <cursor object at 0x04815028; closed: 0>

-----------------------------------------
Selecting from Jobs into subset result...
loCursor2 (just created): <cursor object at 0x047B2F28; closed: 0>
current transaction is aborted, commands ignored until end of transaction block

Stack trace:
 >  File "J:\Python\Applications\SpeedTest\TestPostgreSQLPurePython2.py", line 49, in <module>
 >    loCursor2.execute(f"create temporary table TmpSubset as select * from Jobs where RowID % 100 = 0")

为什么 Python / psycopg2 无法在原始连接上使用新游标 (loCursor2),在“例外”触发后? 有任何想法吗?

您应该阅读您收到的错误消息:

sycopg2.errors.InFailedSqlTransaction:当前事务被中止,命令被忽略,直到事务块结束

一旦出现错误,您需要在继续之前结束事务(回滚),因此将其添加到您的异常块中。

loConnection.rollback()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM