问题无法重现,您需要进行更多的调查。你必须分享更多关于你的数据库表,你的Python代码和服务器操作系统的细节。
您也可以与我们分享附加到Python的strace
,以便我们可以看到查询期间实际发生了什么。
wait_event_type = Client: 服务器进程正在等待来自用户应用程序的套接字上的某些活动,服务器期望发生独立于其内部进程的事件。 wait_event
将识别特定的等待点。
wait_event = ClientRead: 等待 ClientRead
的会话已完成处理上一个查询,并等待客户端发送下一个请求。这样的会话可能会阻止任何操作的唯一方法是它的状态为 idle in transaction
。所有锁都将保持到事务结束,事务完成后不再保持任何锁。
Idle in transaction: 活动可以是 idle
(即等待客户端命令),idle in transaction
(在 BEGIN
块中等待客户端)或命令类型名称,如 SELECT
。如果服务器进程当前正在等待由另一个会话持有的锁,则附加等待。
问题可能与以下内容有关:
- 网络问题
- 在某个地方存在未提交的事务,已经创建了相同的表名。
- 事务未提交
您指出这不是提交问题,因为SQL编辑器也会执行相同的操作,但在您的问题中,您指定编辑器成功创建了表。
在pgModeler中,您可以看到空闲
,这意味着会话处于空闲状态,而不是查询。
如果会话处于空闲状态,则pg_stat_activity
的“查询”列显示该会话中执行的最后一个语句。
因此,这仅意味着所有这些会话都使用ROLLBACK语句正确结束了它们的事务。
如果会话长时间保持在事务中空闲
状态,则始终存在应用程序错误,即应用程序未结束事务。
您可以做两件事:
.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)""")
传统方式
如果您不想自动提交事务,您需要在执行execute
后手动调用.commit()
。
SELECT (row_number() over())::integer "id", "col" FROM tbl2
返回什么?;-) 另外,您是预期表的副本还是随时间更新的计算表(视图)? - Martial P