Python在使用Psycopg2执行cursor.execute()时挂起

Python在使用Psycopg2执行cursor.execute()时挂起,python,postgresql,cursor,execute,Python,Postgresql,Cursor,Execute,我目前的Python脚本有一个问题,当我从cursor.execute()为一个特定函数执行SQL函数时,它会运行该函数,函数完成,然后脚本挂起大约五个小时,然后再继续程序的其余部分 我在pgAdminIII中观察函数从Python调用时的服务器状态,当函数完成时,服务器只显示与Python用户的打开连接。在它将在事务中空闲之前,但在添加conn.set_隔离级别(0)之后,它仅显示打开的连接 我还在cursor.execute()周围进行了打印,但执行下面的打印语句需要五个小时。我已尝试断开连

我目前的Python脚本有一个问题,当我从cursor.execute()为一个特定函数执行SQL函数时,它会运行该函数,函数完成,然后脚本挂起大约五个小时,然后再继续程序的其余部分

我在pgAdminIII中观察函数从Python调用时的服务器状态,当函数完成时,服务器只显示与Python用户的打开连接。在它将在事务中空闲之前,但在添加conn.set_隔离级别(0)之后,它仅显示打开的连接

我还在cursor.execute()周围进行了打印,但执行下面的打印语句需要五个小时。我已尝试断开连接并重新启动,但无效。我将函数调用完全从脚本中剥离,因此它是脚本处理的唯一进程。什么都没起作用

困难在于双方都将对方视为问题的根源。我假设这是这个特定功能的某种交互作用。也许在运行特定函数后,postgres没有向python发送信号?其他函数都没有相同执行方法的问题

想法?解决? -我在考虑超时,但运行时间可以在20分钟到2小时之间变化。 -它运行的函数生成一个表,只返回一个声明“Complete”的字符串,所有操作在它作为活动函数在服务器状态下消失后都会在数据库中进行说明

以下是我用于复制问题的代码,与我的主脚本分离:

#!/usr/bin/env python

import sys
import os
import smtplib
import ftplib
import gzip
import logging
import shutil
import argparse
import traceback
import subprocess
from email.mime.text import MIMEText

import psycopg2
import psycopg2.extras
import psycopg2.extensions
from psycopg2 import OperationalError

pg_db    = "ppl"
pg_port  = "5432"
pg_user  = "<user>"
pg_pass  = "<pass>"
pg_host  = "<host>"

# connect to database
try:
    conn = psycopg2.connect(database=pg_db,
                            port=pg_port, 
                            user=pg_user, 
                            password=pg_pass, 
                            host=pg_host)
    conn.set_isolation_level(0)
except:
    print "Unable to connect to the database."

cur = conn.cursor()

print 'Starting select <function1>'
cur.execute("select <function1>(999999, null );")
print 'Assign variable...'
a = cur.fetchall()
print 'Done'

print 'Starting select <function2>'
cur.execute("select <function2>(999999, null );")
print 'Assign variable...'
b = cur.fetchall()
print 'Done'

print a
print b

conn.close()
sys.exit()
#/usr/bin/env python
导入系统
导入操作系统
导入smtplib
进口ftplib
导入gzip
导入日志记录
进口舒蒂尔
导入argparse
导入回溯
导入子流程
从email.mime.text导入MIMEText
导入psycopg2
导入psycopg2.extras
导入psycopg2.extensions
从psycopg2导入错误
pg_db=“ppl”
pg_port=“5432”
pg_user=“”
pg_pass=“”
pg_host=“”
#连接到数据库
尝试:
conn=psycopg2.connect(数据库=pg_db,
端口=pg_端口,
用户=pg_用户,
密码=pg_通行证,
主机=pg_主机)
连接设置隔离级别(0)
除:
打印“无法连接到数据库”
cur=连接光标()
打印“开始选择”
cur.execute(“选择(9999999,null);”)
打印“分配变量…”
a=cur.fetchall()
打印“完成”
打印“开始选择”
cur.execute(“选择(9999999,null);”)
打印“分配变量…”
b=cur.fetchall()
打印“完成”
打印
打印b
康涅狄格州关闭
sys.exit()
然后我运行了一个strace,结果如下:

<previous function statements for about 4k lines>

write(1, "Starting select <function>"..., 45) = 45
sendto(3, "Q\0\0\0009select <function>"..., 58, MSG_NOSIGNAL, NULL, 0) = 58
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "T\0\0\0001\0\1<function_name>\0"..., 16384, 0, NULL, NULL) = 500
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0mSINFO\0C00000\0Mv_eval_table "..., 16384, 0, NULL, NULL) = 110
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\4\247SINFO\0C00000\0Mcmd := CREATE"..., 16384, 0, NULL, NULL) = 1192
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\23hSINFO\0C00000\0Mcmd := \t--For"..., 16384, 0, NULL, NULL) = 4969
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 84
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 672
...
brk(0xbe9000)                           = 0xbe9000
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 84
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 168
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 1008
...

<does this for about 600k more lines before executing the rest of the script, I am assuming it is indefinitely looping until a timeout>

写入(1,“开始选择”…,45)=45
发送到(3,“Q\0\0\0009选择”…,58,MSG_NOSIGNAL,NULL,0)=58
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“T\0\0\0001\0\1\0”…,16384,0,NULL,NULL)=500
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0mSINFO\0C00000\0Mv\u评估表”…,16384,0,NULL,NULL)=110
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\4\247SINFO\0C00000\0Mcmd:=创建”…,16384,0,NULL,NULL)=1192
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\23hSINFO\0C00000\0Mcmd:=\t——对于“…,16384,0,NULL,NULL)=4969
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0SSINFO\000000\0Mlicense\u row\u i”…,16384,0,NULL,NULL)=84
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0SSINFO\000000\0Mlicense\u row\u i”…,16384,0,NULL,NULL)=672
...
brk(0xbe9000)=0xbe9000
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0SSINFO\000000\0Mlicense\u row\u i”…,16384,0,NULL,NULL)=84
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0SSINFO\000000\0Mlicense\u row\u i”…,16384,0,NULL,NULL)=168
poll([{fd=3,events=POLLIN | POLLERR}],1,-1)=1([{fd=3,revents=POLLIN}])
recvfrom(3,“N\0\0\0SSINFO\000000\0Mlicense\u row\u i”…,16384,0,NULL,NULL)=1008
...
接下来,我为一个函数运行了一个cProfile,该函数包装了调用第二个函数的第二块代码:

Tue Jan 15 16:04:50 2013    function2_prof

         7 function calls in 15755.988 CPU seconds

   Random listing order was used

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 {method 'cursor' of 'psycopg2._psycopg.connection' objects}
        1    0.000    0.000 15755.988 15755.988 test_sql_sub2.py:48(LR2)
        1 15755.988 15755.988 15755.988 15755.988 {method 'execute' of 'psycopg2._psycopg.cursor' objects}
        1    0.000    0.000 15755.988 15755.988 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'close' of 'psycopg2._psycopg.cursor' objects}
        1    0.000    0.000    0.000    0.000 {method 'fetchall' of 'psycopg2._psycopg.cursor' objects}
2013年1月15日星期二16:04:50功能2
15755.988 CPU秒内7次函数调用
使用随机列表顺序
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.000 0.000 0.000 0.000{“psycopg2.\u psycopg.connection”objects}的方法“cursor”
1 0.000 0.000 15755.988 15755.988 test_sql_sub2.py:48(LR2)
1 15755.988 15755.988 15755.988 15755.988{psycopg2.\u psycopg.cursor'objects}的方法'execute'
1    0.000    0.000 15755.988 15755.988 :1()
1 0.000 0.000 0.000 0.000{方法'disable'的''lsprof.Profiler'对象}
1 0.000 0.000 0.000 0.000{psycopg2.\u psycopg.cursor'objects}的方法“关闭”
1 0.000 0.000 0.000 0.000{方法'fetchall'的'psycopg2.\u psycopg.cursor'objects}

我认为您的功能比您意识到的要多。看看你的背带:

brk(0xbe9000)                           = 0xbe9000
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 84
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 168
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "N\0\0\0SSINFO\0C00000\0Mlicense_row_i"..., 16384, 0, NULL, NULL) = 1008
brk
的意思是“给我更多内存”,所以很明显Python正在积累数据<代码>轮询检查是否有任何数据等待;正返回值(此处为
1
)表示存在。和
recvfrom
读取该数据并返回读取的字节数

看来Postgres向您发送了大量数据,以至于需要花费大量时间才能接收。我对Postgres的wire格式不太了解,但每次投票中的
许可证\u行\u I…
听起来确实像你
raise info 'license_row_id := %', rec.license_row_id;