Python 3.x 在Python中使用`with`时,如何处理数据库类中的连接错误?
在下面的数据库类中,如果连接失败,将打印我的错误。但是,系统错误也会打印出来,因为Python 3.x 在Python中使用`with`时,如何处理数据库类中的连接错误?,python-3.x,class,psycopg2,Python 3.x,Class,Psycopg2,在下面的数据库类中,如果连接失败,将打印我的错误。但是,系统错误也会打印出来,因为\uuuu退出\uuu代码触发 AttributeError:“数据库”对象没有属性“\u conn” 我应该如何处理这种情况? 试试/除了还是有更好的方法 import psycopg2 import mysecrets as ms from time import time class Database(object): def __init__(self, localhost=False):
\uuuu退出\uuu
代码触发
AttributeError:“数据库”对象没有属性“\u conn”
我应该如何处理这种情况?试试/除了
还是有更好的方法
import psycopg2
import mysecrets as ms
from time import time
class Database(object):
def __init__(self, localhost=False):
try:
print(f"ATTEMPTING DATABASE CONNECTION")
self._conn = psycopg2.connect(
f"""
dbname = {ms.LOCALDB_NAME if localhost else ms.DB_NAME}
port = {ms.LOCALDB_PORT if localhost else ms.DB_PORT}
user = {ms.LOCALDB_USER if localhost else ms.DB_USER}
password = {ms.LOCALDB_PASS if localhost else ms.DB_PASS}
host = {ms.LOCALDB_HOST if localhost else ms.DB_HOST}
"""
)
self._cursor = self._conn.cursor()
print(f"CONNECTED TO DATABASE\n")
except Exception as error:
print(f"UNABLE TO CONNECT TO DATABASE\n{error}")
def __enter__(self):
return self
def __del__(self):
self.connection.close()
def __exit__(self, exc_type, exc_value, traceback):
self.connection.close()
@property
def connection(self):
return self._conn
@property
def cursor(self):
return self._cursor
def commit(self):
self.connection.commit()
def query(self, sql, params=None):
self.cursor.execute(sql, params or ())
def fetchall(self):
return self.cursor.fetchall()
def fetchone(self):
return self.cursor.fetchone()
if __name__ == "__main__":
start_time = time()
with Database() as db:
elapsed_time = round(time() - start_time, 2)
print(f"Testing database connection took {elapsed_time} seconds.")
在这种情况下,您可以先初始化
self.\u conn
,然后再尝试,作为self.\u conn=None
,这样它就存在了。然后,在\uu退出\uuu
,关闭
等处,用
if self._conn is not None:
self._conn.close()
self._conn = None
然而,我认为这不是一个好的设计,因为它忽略了一般的异常错误。这可能不是连接错误。即使是这样,最终也会得到一个未初始化的对象。这没有用,会导致以后的错误。最好早点抓住它们,让它从\uuuu init\uuuuu
传递,让任何实例化它的东西来处理它 在这种情况下,您可以在尝试之前,首先将self.\u conn
初始化为self.\u conn=None
,这样它就存在了。然后,在\uu退出\uuu
,关闭
等处,用
if self._conn is not None:
self._conn.close()
self._conn = None
然而,我认为这不是一个好的设计,因为它忽略了一般的异常错误。这可能不是连接错误。即使是这样,最终也会得到一个未初始化的对象。这没有用,会导致以后的错误。最好早点抓住它们,让它从\uuuu init\uuuuu
传递,让任何实例化它的东西来处理它 首先,捕获异常而不是特定错误是一种反模式。
在Python中,您应该知道从函数中抛出了哪些异常,并相应地处理它们
其次,如果对psycopg2.connect
或\u conn.cursor()
的调用引发任何错误,那么代码将捕获异常,并且实例变量\u conn
和\u cursor
从未设置。
这就是您的属性错误的原因
在我看来,正确的处理方法是引发错误,如果数据库类无法连接到数据库,或者让使用该类的任何代码处理错误,则不要继续执行
class Database(object):
def __init__(self, localhost=False):
try:
print(f"ATTEMPTING DATABASE CONNECTION")
self._conn = psycopg2.connect(
f"""
dbname = {ms.LOCALDB_NAME if localhost else ms.DB_NAME}
port = {ms.LOCALDB_PORT if localhost else ms.DB_PORT}
user = {ms.LOCALDB_USER if localhost else ms.DB_USER}
password = {ms.LOCALDB_PASSWORD if localhost else ms.DB_PASSWORD}
host = {ms.LOCALDB_HOST if localhost else ms.DB_HOST}
"""
)
self._cursor = self._conn.cursor()
print(f"CONNECTED TO DATABASE\n")
except psycopg2.Error as error:
raise ValueError(f"UNABLE TO CONNECT TO DATABASE\n{error}") from None
可能有比ValueError
更好的异常可供使用。首先,捕获异常而不是特定错误是一种反模式。
在Python中,您应该知道从函数中抛出了哪些异常,并相应地处理它们
其次,如果对psycopg2.connect
或\u conn.cursor()
的调用引发任何错误,那么代码将捕获异常,并且实例变量\u conn
和\u cursor
从未设置。
这就是您的属性错误的原因
在我看来,正确的处理方法是引发错误,如果数据库类无法连接到数据库,或者让使用该类的任何代码处理错误,则不要继续执行
class Database(object):
def __init__(self, localhost=False):
try:
print(f"ATTEMPTING DATABASE CONNECTION")
self._conn = psycopg2.connect(
f"""
dbname = {ms.LOCALDB_NAME if localhost else ms.DB_NAME}
port = {ms.LOCALDB_PORT if localhost else ms.DB_PORT}
user = {ms.LOCALDB_USER if localhost else ms.DB_USER}
password = {ms.LOCALDB_PASSWORD if localhost else ms.DB_PASSWORD}
host = {ms.LOCALDB_HOST if localhost else ms.DB_HOST}
"""
)
self._cursor = self._conn.cursor()
print(f"CONNECTED TO DATABASE\n")
except psycopg2.Error as error:
raise ValueError(f"UNABLE TO CONNECT TO DATABASE\n{error}") from None
可能有比使用ValueError
更好的异常。Hi Keith。你的意思是“让任何实例化它的东西来处理它”吗?是的。要么让psycopg2错误通过,要么提出一个可能对你的应用程序更有意义的错误。但是,我会使用。。。来自错误
,而不是。。。从“无”
,这样您就不会丢失基线原因。嗨,基思。你的意思是“让任何实例化它的东西来处理它”吗?是的。要么让psycopg2错误通过,要么提出一个可能对你的应用程序更有意义的错误。但是,我会使用。。。来自错误
,而不是。。。从“无”
,这样您就不会丢失参考底图原因。