每次关闭数据库是否正确?

时间:2021-01-30 12:20:25

标签: python database sqlite

我需要用电报机器人处理数据库,我写这个来管理 db 文件:

class DBfunction:
    def __init__(self, dbname = 'example.db'):
        self.debname = dbname
        self.conn = sqlite3.connect(dbname)
        self.cur = self.conn.cursor()

    def search_db(self, telegram_id):
        telegram_id = (telegram_id,)
        sql = 'SELECT * FROM user WHERE id = ?;'
        self.cur.execute(sql,telegram_id)
        row = self.cur.fetchone()
        self.conn.close()

        return row

    def newuser_db(self, tele_id, name, nick):
        par = (tele_id, name, nick, 0)
        #print(par)

        sql = 'INSERT INTO user VALUES(?,?,?,?);'

        self.cur.execute(sql, par)
        self.conn.commit()
        self.conn.close()

在类的每个定义中正确使用 close() 还是有更好的方法?

3 个答案:

答案 0 :(得分:3)

这真的取决于你想要达到的目标。

您正在做的是在查询运行后关闭连接。这本身没有任何问题。

但是,在不断进行大量查询的应用程序中,您可能不想支付尝试不断打开和关闭连接的开销。

因此,您可以创建一个连接池(称为连接池),您可以在其中存储可供其他查询重复使用的连接。这是一种非常普遍的做法,您可以在网上阅读。

但同样,这真的取决于您要实现的目标。如果您的应用程序没有进行太多查询,并且您在打开和关闭连接上花费的几毫秒(如果有的话)对您来说无关紧要,那么打开和关闭连接的开销可能不是您需要担心的。< /p>

此外,打开和关闭连接的一种更安全的方法是使用 with 子句。你可以阅读它的作用。语法类似于:

with cur.open() as cur:
    # do your queries

finally:
    # close connection

这可确保您的连接不会在您执行查询时出现错误时意外打开。

答案 1 :(得分:1)

你不应该在你的类方法中关闭连接。理想情况下,您应该在类中有一个 close 方法,并且使用这个 DB 类的程序应该负责在完成后关闭连接。

理想情况下,类应该是这样的:

class DBfunction:
    def __init__(self, dbname = 'example.db'):
        self.debname = dbname
        self.conn = sqlite3.connect(dbname)
        self.cur = self.conn.cursor()

    def search_db(self, telegram_id):
        telegram_id = (telegram_id,)
        sql = 'SELECT * FROM user WHERE id = ?;'
        self.cur.execute(sql,telegram_id)
        row = self.cur.fetchone()
        return row

    def newuser_db(self, tele_id, name, nick):
        par = (tele_id, name, nick, 0)
        #print(par)
        sql = 'INSERT INTO user VALUES(?,?,?,?);'
        self.cur.execute(sql, par)
        self.conn.commit()

     def close(self)
        self.conn.close()

答案 2 :(得分:1)

实际上根本不需要执行 close。当程序终止时,连接将自动关闭(并且任何未完成的事务都将回滚)。当然,如果您要创建 DBFunction 的多个实例,那是另一个考虑因素——您不一定需要多个打开的连接。但是一个设计良好的 DBFunction 类应该不需要多个实例。您还可以添加一个“析构函数”方法,以便当您的 DBFunction 实例被垃圾回收时,连接将被关闭:

class DBfunction:
    def __init__(self, dbname = 'example.db'):
        self.debname = dbname
        self.conn = sqlite3.connect(dbname)
        self.cur = self.conn.cursor()

    # make "private" -- not intended to be called by client
    def _close(self):
        if self.conn: # but check to make sure it has not been called by client!
            self.conn.close()
            self.conn = None

    def __del__(self):
        self._close()

    """ Other methods """
相关问题