cx_Oracle.DatabaseError: DPI-1039: statement was already closed
cx_Oracle.DatabaseError: DPI-1039: statement was already closed
已升级到最新的 Cx_Oracle 版本(5.1.3 到 7.1.3),现在我的所有代码都损坏了。尝试传递游标时似乎出现问题。
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#print cur.fetchall()
return cur
我在 fetchall 中得到了正确的数据,所以我知道它连接正确并且 return 得到了有效结果。所以我把它注释掉了。
在我调用它的其他脚本中,行现在应该正确存储光标吗?
rows = con.select_query_remy(sql)
当我从其他脚本 fetchall()
进入下方并收到错误消息时。
print rows.fetchall()
cx_Oracle.DatabaseError: DPI-1039: statement was already closed
有什么想法吗?
满db.py
import cx_Oracle
class db:
list ={}
def __init__(self):
'''
AMFM Python DB connectors
'''
db.list["disprod"] = [999,"disprod.prod.com"]
db.list["prodqry"] = [999,"prodqry.prod.com"]
db.list["amfmprod"] = [999,"amfmprod.prod.com"]
db.list["esriprod"] = [999,"esriprod.prod.com"]
db.list["amfmtest"] = [999,"amfmtest.prod.com"]
db.list["amfmdev"] = [999,"CCTdAMFM.prod.com"]
db.list["amfmtran"] = [999,"amfmtran.prod.com"]
def setup(self,env, username, password):
self.username = username
self.password = password
self.env = env
self.port = db.list[env][0]
self.ip = db.list[env][1]
if env == "prodqry":
self.env = "prodqry.world"
elif env == "amfmprod":
self.env = "amfmprod.world"
elif env == "esriprod":
self.env = "esriprod.world"
else:
self.env = env
self.connection = self.username+"/"+self.password+"@"+self.ip+":"+str(self.port)+"/"+self.env
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
return cur
在另一个 python 中,我创建了一个新数据库并尝试取回光标。
con = db()
con.setup("xxx","user","password")
rows = con.select_query_remy(sql)
print rows.fetchall()
结果:
Traceback (most recent call last):
File "C:\Python27\ArcGIS10.5\test\test.py", line 30, in <module>
print rows.fetchall()
cx_Oracle.DatabaseError: DPI-1039: statement was already closed
如果我 return fetchall() 数据会出现。当我传递光标本身时发生错误。
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#return cur
return cur.fetchall()
为什么我不能像过去那样传递光标?有什么想法吗?
您的错误与 with
-block(也称为 上下文管理器)有关。让我在 select_query_remy
函数中添加一些注释:
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con: # connects to database
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
return cur # closes connection (invalidates cursor too!)
由于with
-块管理数据库连接的上下文,所以连接将在块退出后关闭。
要修复错误,我建议直接在函数内执行 fetchall
,然后在函数外处理该数据。 (你已经有点明白了。)
我在查询 Oracle 数据库时 运行 进入此错误消息。我相信如果数据库中有 LOB(大对象)就会发生这种情况,而在我查询过的所有 Oracle 数据库中都没有这种情况。
由于我正在使用 Jupyter 进行原型设计,所以我更喜欢使用上下文管理器 (with) 语句,如果我必须在单独的单元格中添加 .close() 语句,这会使操作查询结果变得更加困难。
我的解决方法实际上是使用内置的 deepcopy
函数(我尝试使用 .copy()
但这也不起作用。任何进一步的 manipulation/display 数据产生相同的结果错误。
所以我给你的解决方案如下:
from copy import deepcopy
import cx_Oracle
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#print cur.fetchall()
return deepcopy(cur.fetchall())
如果我遇到的是同一个问题,我相信这应该可以解决您的问题。
已升级到最新的 Cx_Oracle 版本(5.1.3 到 7.1.3),现在我的所有代码都损坏了。尝试传递游标时似乎出现问题。
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#print cur.fetchall()
return cur
我在 fetchall 中得到了正确的数据,所以我知道它连接正确并且 return 得到了有效结果。所以我把它注释掉了。
在我调用它的其他脚本中,行现在应该正确存储光标吗?
rows = con.select_query_remy(sql)
当我从其他脚本 fetchall()
进入下方并收到错误消息时。
print rows.fetchall()
cx_Oracle.DatabaseError: DPI-1039: statement was already closed
有什么想法吗?
满db.py
import cx_Oracle
class db:
list ={}
def __init__(self):
'''
AMFM Python DB connectors
'''
db.list["disprod"] = [999,"disprod.prod.com"]
db.list["prodqry"] = [999,"prodqry.prod.com"]
db.list["amfmprod"] = [999,"amfmprod.prod.com"]
db.list["esriprod"] = [999,"esriprod.prod.com"]
db.list["amfmtest"] = [999,"amfmtest.prod.com"]
db.list["amfmdev"] = [999,"CCTdAMFM.prod.com"]
db.list["amfmtran"] = [999,"amfmtran.prod.com"]
def setup(self,env, username, password):
self.username = username
self.password = password
self.env = env
self.port = db.list[env][0]
self.ip = db.list[env][1]
if env == "prodqry":
self.env = "prodqry.world"
elif env == "amfmprod":
self.env = "amfmprod.world"
elif env == "esriprod":
self.env = "esriprod.world"
else:
self.env = env
self.connection = self.username+"/"+self.password+"@"+self.ip+":"+str(self.port)+"/"+self.env
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
return cur
在另一个 python 中,我创建了一个新数据库并尝试取回光标。
con = db()
con.setup("xxx","user","password")
rows = con.select_query_remy(sql)
print rows.fetchall()
结果:
Traceback (most recent call last):
File "C:\Python27\ArcGIS10.5\test\test.py", line 30, in <module>
print rows.fetchall()
cx_Oracle.DatabaseError: DPI-1039: statement was already closed
如果我 return fetchall() 数据会出现。当我传递光标本身时发生错误。
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#return cur
return cur.fetchall()
为什么我不能像过去那样传递光标?有什么想法吗?
您的错误与 with
-block(也称为 上下文管理器)有关。让我在 select_query_remy
函数中添加一些注释:
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con: # connects to database
cur = None
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
return cur # closes connection (invalidates cursor too!)
由于with
-块管理数据库连接的上下文,所以连接将在块退出后关闭。
要修复错误,我建议直接在函数内执行 fetchall
,然后在函数外处理该数据。 (你已经有点明白了。)
我在查询 Oracle 数据库时 运行 进入此错误消息。我相信如果数据库中有 LOB(大对象)就会发生这种情况,而在我查询过的所有 Oracle 数据库中都没有这种情况。
由于我正在使用 Jupyter 进行原型设计,所以我更喜欢使用上下文管理器 (with) 语句,如果我必须在单独的单元格中添加 .close() 语句,这会使操作查询结果变得更加困难。
我的解决方法实际上是使用内置的 deepcopy
函数(我尝试使用 .copy()
但这也不起作用。任何进一步的 manipulation/display 数据产生相同的结果错误。
所以我给你的解决方案如下:
from copy import deepcopy
import cx_Oracle
def select_query_remy(self,sql,params=None):
with cx_Oracle.connect(self.connection) as con:
cur = con.cursor()
if params:
cur.execute(sql,params)
else:
cur.execute(sql)
#print cur.fetchall()
return deepcopy(cur.fetchall())
如果我遇到的是同一个问题,我相信这应该可以解决您的问题。