Закрытие соединения cx_Oracle с учетом сбоя базы данных - PullRequest
3 голосов
/ 09 марта 2011

Следующий код 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()

Но если при запуске этого сценария происходит сбой базы данных, NameError повышается:

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

Для меня это имеет смысл: cx_Oracle не смог создать экземпляр соединения, поэтому переменная conn не была установлена ​​и, следовательно, не имеет close() метода.

В Python, как лучше всего обеспечить закрытие соединения с вашей базой данных, при этом все еще корректно обрабатывая состояние неработающей базы данных?

Мне кажется, что делать что-то вроде следующего - огромный шаг:

finally:
    try:
        conn.close()
    except NameError:
        pass

Ответы [ 2 ]

7 голосов
/ 28 августа 2014

Вы можете попробовать инициализировать 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()
0 голосов
/ 10 марта 2011

(не совсем ответ, но комментарии не имеют хорошего форматирования)

Попробуйте:

#!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

Не идеально, но должно работать лучше.Мне также интересно, почему так много вложения.Почему бы не сделать это:

#!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

Кстати, у меня есть предположение, что соединение и курсор закрываются автоматически при выходе, устраняя необходимость их явного закрытия.

...