保证数据库连接在课堂上使用后关闭?

时间:2017-10-31 20:24:13

标签: python python-3.x

我有一个包装类,我将其子类化为我们使用的许多数据库连接。我想要一些与try/finally功能类似的东西,但仍然给我一个类的灵活性和子类化潜力。这是我的基类,我想替换__del__方法,因为我已经读过某个地方,无法保证何时运行。

class DatabaseConnBase:
    def __init__(self, conn_func, conn_info: MutableMapping):
        self._conn = None
        self.conn_func = conn_func
        self.conn_info = conn_info

    def _initialize_connection(self):
        self._conn = self.conn_func(**self.conn_info)

    @property
    def conn(self):
        if not self._conn:
            self._initialize_connection()
        return self._conn

    @property
    def cursor(self):
        if not self._conn:
            self._initialize_connection()
        return self._conn.cursor()

    def __del__(self):
        if self._conn:
            self._conn.close()

    def commit(self):
        if not self._conn:
            raise AttributeError(
                'The connection has not been initialized, unable to commit '
                'transaction.'
            )
        self._conn.commit()

    def execute(
            self,
            query_or_stmt: str,
            verbose: bool = True,
            has_res: bool = False,
            auto_commit: bool = False
    ) -> Optional[Tuple[Any]]:
        """
        Creates a new cursor object, and executes the query/statement.  If
        `has_res` is `True`, then it returns the list of tuple results.

        :param query_or_stmt: The query or statement to run.
        :param verbose: If `True`, prints out the statement or query to STDOUT.
        :param has_res: Whether or not results should be returned.
        :param auto_commit: Immediately commits the changes to the database
         after the execute is performed.

        :return: If `has_res` is `True`, then a list of tuples.
        """
        cur = self.cursor
        if verbose:
            logger.info(f'Using {cur}')
            logger.info(f'Executing:\n{query_or_stmt}')

        cur.execute(query_or_stmt)

        if auto_commit:
            logger.info('Committing transaction...')
            self.commit()

        if has_res:
            logger.info('Returning results...')
            return cur.fetchall()

1 个答案:

答案 0 :(得分:1)

根据相关问题的最佳答案:What is the __del__ method, How to call it?

当您的对象被垃圾收集时,将调用height方法,但正如您所指出的那样,无法保证在销毁对象的引用之后多久会发生这种情况。

在您的情况下,由于您在尝试关闭连接之前检查是否存在连接,因此可以安全地多次调用max-height方法,因此您可以在销毁引用之前简单地调用它。你的对象。