我正在创建一个类来管理与 Firebird 数据库的连接。将安装 Firebird 服务以方便与数据库的多个连接。不幸的是,我的软件部署的环境可能不稳定,我不能总是保证 Firebird 服务在我尝试连接时将运行,或者在我建立连接后它将继续运行。
为了集中错误处理,我决定代码的不同部分不会以任何方式直接使用数据库游标。相反,我将从连接管理器公开 query()
和 dml()
方法。考虑到下面的代码(为简洁起见,未包含一些代码),这在一定程度上是有效的。
class DBConnection(object):
# self._conn is an instance of kinterbasdb.connect()
def query(self, query, params = None):
cursor = self._conn.cursor()
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
return [[x[0].title() for x in cursor.description]] + [r for r in cursor.fetchall()]
def dml(self, query, params = None):
cursor = self._conn.cursor()
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
self._conn.commit()
当 Firebird 服务因某种原因停止或无法访问时,问题就会出现。我希望 self._conn.cursor() 会抛出异常,这将使执行以下操作变得简单:
class DBConnection(object):
# self._conn is an instance of kinterbasdb.connect()
def cursor(self):
try:
return self._conn.cursor()
except:
# Error handling code here, possibly reconnect, display alert.
def query(self, query, params = None):
cursor = self.cursor()
def dml(self, query, params = None):
cursor = self.cursor()
不幸的是,当我请求游标时没有抛出异常。直到调用 cursor.execute()
时我才意识到这个问题。这意味着,如果我想正确集中我的错误处理,我必须这样做:
class DBConnection(object):
# self._conn is an instance of kinterbasdb.connect()
def cursor(self):
try:
cursor = self._conn.cursor()
cursor.execute("Select NULL From <sometable>")
return cursor
except:
# Error handling code here, possibly reconnect, display alert.
这需要对我的数据库进行额外的往返,浪费事务(Firebird 数据库对数据库生命周期内的事务总数有硬性上限),而且通常感觉不对。我想知道,是否有人遇到过与 Python 数据库 API 的其他实现类似的问题,如果有,他们是如何克服的?
最佳答案
我正在测试对我的类的以下修改,我相信这些修改将以最少的代码重复实现我想要的集中处理。它们还稍微简化了查询和 dml 方法,并且消除了我想要避免的额外查询(心跳)。
class DBConnection(object):
# self._conn is an instance of kinterbasdb.connect()
def query(self, query, params = None):
cursor = self._conn.cursor()
self.execute(cursor, query, params)
return [[x[0].title() for x in cursor.description]] +
[r for r in cursor.fetchall()]
def dml(self, query, params = None):
cursor = self._conn.cursor()
self.execute(cursor, query, params)
self._conn.commit()
def execute(self, cursor, query, params = None):
try:
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
except Exception, e:
# Handling
关于Python 数据库游标异常时序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6217796/