在允许Down数据库的同时关闭cx_Oracle连接

Art*_*zer 3 python cx-oracle database-connection nameerror try-finally

cx_Oracle数据库启动时,以下代码可以正常工作:

#!C:\Python27
import cx_Oracle

try:
    conn = cx_Oracle.connect("scott/tiger@oracle")

    try:
        curs = conn.cursor()
        curs.execute("SELECT dummy FROM sys.dual")
        print curs.fetchone()[0]
    finally:
        curs.close()
finally:
    conn.close()
Run Code Online (Sandbox Code Playgroud)

但是,如果在运行此脚本时数据库发生故障,NameError则会引发a:

Traceback (most recent call last):
  File "C:\Users\ArtMetzer\Documents\Code\Python\db_conn_test.py", line 14, in <module>
    conn.close()
NameError: name 'conn' is not defined
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义: cx_Oracle无法实例化连接,因此变量conn永远不会被设置,因此没有close()方法.

在Python中,什么是确保数据库连接关闭的最佳方法,同时仍然优雅地处理down数据库的条件?

做类似以下的事情对我来说似乎是一个巨大的障碍:

finally:
    try:
        conn.close()
    except NameError:
        pass
Run Code Online (Sandbox Code Playgroud)

Mad*_*ist 7

您可以尝试初始化conn为类似于None之前的操作并在finally块中进行测试.这是有效的,因为连接被设置为其他东西的唯一位置是它打开时.所以开放意味着非None,None意味着未开放:

#!C:\Python27
import cx_Oracle

conn = None
try:
    conn = cx_Oracle.connect("scott/tiger@oracle")

    try:
        curs = conn.cursor()
        curs.execute("SELECT dummy FROM sys.dual")
        print curs.fetchone()[0]
    finally:
        curs.close()
finally:
    if conn is not None:
        conn.close()
Run Code Online (Sandbox Code Playgroud)


tsh*_*ang -3

(不完全是答案,但评论没有很好的格式)

尝试这个:

#!C:\Python27
import cx_Oracle

try:
    conn = cx_Oracle.connect("scott/tiger@oracle")

    try:
        curs = conn.cursor()
        curs.execute("SELECT dummy FROM sys.dual")
        print curs.fetchone()[0]
    finally:
        curs.close()
        conn.close()
except Exception as e:
    print e
Run Code Online (Sandbox Code Playgroud)

不理想,但应该工作得更好。我也想知道为什么要这么多嵌套。为什么不这样做:

#!C:\Python27
import cx_Oracle

try:
    conn = cx_Oracle.connect("scott/tiger@oracle")
    curs = conn.cursor()
    curs.execute("SELECT dummy FROM sys.dual")
    print curs.fetchone()[0]
    curs.close()
    conn.close()
except Exception as e:
    print e
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我假设连接和游标将在退出时自动关闭,从而无需显式关闭它们。