问题不可重现,您必须进行更多调查。您必须分享有关您的数据库表、python 代码和服务器操作系统的更多详细信息。
您还可以与我们分享strace
附加到 Python 的内容,以便我们了解查询过程中实际发生的情况。
wait_event_type = Client:服务器进程正在等待来自用户应用程序的套接字上的某些活动,并且服务器期望发生一些独立于其内部进程的事情。wait_event
将确定具体的等待点。
wait_event = ClientRead:等待的会话ClientRead
完成处理最后一个查询并等待客户端发送下一个请求。这种会话可以阻止任何东西的唯一方法是它的状态是idle in transaction
. 所有的锁都被持有直到事务结束,一旦事务结束就不会持有任何锁。
事务中的空闲:活动可以是idle
(即等待客户端命令)、idle in transaction
(等待BEGIN
块内的客户端)或命令类型名称,例如SELECT
. 此外,如果服务器进程当前正在等待另一个会话持有的锁,则会附加等待。
问题可能与以下有关:
- 网络问题
- 未提交的事务在某个地方创建了相同的表名。
- 事务未提交
您指出这不是提交问题,因为 SQL 编辑器执行相同操作,但在您的问题中,您指定编辑器成功创建表。
在您看到的 pgModeleridle
中,这意味着会话是空闲的,而不是查询。
如果会话空闲,“查询”列pg_stat_activity
显示该会话中最后执行的语句。所以这仅仅意味着所有这些会话都使用 ROLLBACK 语句正确地结束了他们的事务。
如果会话保持状态idle in transaction
较长时间,则始终是应用程序未结束事务的应用程序错误。
你可以做两件事:
.commit()
解决方案
我发现重现问题的唯一方法是省略该commit
操作。
该模块psycopg2
与Python DB API兼容,因此默认情况下自动提交功能处于关闭状态。
将此选项设置为False
您需要调用conn.commit
以将任何待处理的事务提交到数据库。
启用自动提交
您可以按如下方式启用自动提交:
import psycopg2
connection = None
try:
connection = psycopg2.connect("dbname='myDB' user='myUser' host='localhost' password='myPassword'")
connection.autocommit = True
except:
print "Connection failed."
if(connection != None):
cursor = connection.cursor()
try:
cursor.execute("""CREATE TABLE tbl AS (SELECT (row_number() over())::integer 'id', 'col' FROM tbl2)""")
except:
print("Failed to create table.")
with
陈述
您还可以使用该with
语句自动提交事务:
with connection, connection.cursor() as cursor: # start a transaction and create a cursor
cursor.execute("""CREATE TABLE tbl AS (SELECT (row_number() over())::integer 'id', 'col' FROM tbl2)""")
传统方式
如果您不想自动提交事务,则需要.commit()
在execute
.