Python 数据库游标异常时序

标签 python database exception cursor firebird

我正在创建一个类来管理与 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/

相关文章:

python - 根据列列表转置数据框

python - 如何将选定的数据条目应用到我的 to sql 更新功能?

php - 连接多个数据库并在php中跨数据库加入查询

java - 了解 Mockito 验证背后的语义

python - 如何将参数传递给 win32com 事件处理程序

python - 无循环的 n 个矩阵的乘积运算符

database - 针对 Neo4j 图数据库的关系式查询

java - 没有用于带有 JavaSE 应用程序的 EntityManager 的持久性提供程序?

c++ - 为什么 `throw MyClass' 不起作用而 `throw MyClass()' 起作用?

c# - 使用辅助 UI 消息泵作为启动屏幕时出现异常