sqlite3.编程错误:无法对关闭的数据库进行操作。[Python] [sqlite]

12 投票
3 回答
59114 浏览
提问于 2025-04-18 02:35

我在一个类里用一个通用的函数来执行所有的sqlite查询,这个方法都能正常工作,直到我用一个包含多个项目的列表的for循环。

这是执行sqlite查询的通用函数:

def executeQuery(self, query, params = ()):
        results = {}
        try:
            cur = self.conn.cursor()
            cur.execute(query, params)
            self.conn.commit()
            rows = cur.fetchall()

            results['status'] = 'success'
            result = []
            if rows:
                column = map(lambda x: x[0], cur.description)
                for row in rows:
                    result.append( dict(zip(column, row)) )

            results['results'] = result

        except self.conn.Error, e:
            if self.conn:
                self.conn.rollback()

            print "Error: %s" % e.args[0]
            results['status'] = 'failure'
            results['results'] = e.args[0]

        finally:
            if self.conn:
                self.conn.close()

        return results

而这个循环让我遇到了数据库关闭的错误:

stages = self.getStageByDate(2000)
        for stage in stages['results']:
            print stage['name']
            additives = self.getStageAdditives(stage['name'])
            print additives
            for additive in additives['results']:
                print additive

错误似乎是从getStageAdditives()函数开始的,因为它返回了4个项目,而getStageByDate()只返回了1个。

我觉得在尝试第二次连接之前,数据库的连接没有关闭。这为什么会发生呢?在使用MySQL数据库时没有遇到这个问题。对此有什么解决办法吗?

3 个回答

0

为什么一个业务方法要关闭连接呢?难道应该关闭游标(cursor)吗?如果关闭了连接,那第二次调用 executeQuery 的时候就会失败,因为连接已经不存在了。

3

把这个从代码中去掉

 self.conn.close()

这样做可以解决问题,因为当你想从数据库获取信息时,不能写

conn.close()

15

你说“我觉得在尝试第二次连接数据库之前,数据库的连接没有关闭”,但实际上并没有“第二次连接”到数据库。你使用的是一个连接,我猜这个连接是在你没有展示的类的初始化方法(__init__)中创建的,而这个类里有一个叫execute_query的方法。

我猜你是在这个__init__方法里创建了conn,但在执行完任何查询后就立刻关闭了它。因此,当你执行另一个查询时,这个连接就不可用了。

相反,你应该在查询结束时使用.commit()而不是.close()。不要在finally里做这个,而是在try的最后。这样的话,如果查询成功,事务就会被提交;如果失败,就会在异常处理的部分回滚。

然后,给你的大类添加一个单独的.close()方法,这个方法会调用连接的.close(),并让调用程序在完成所有查询后调用这个方法。这个关闭连接的调用应该放在大程序的finally块里。

撰写回答