在类中重用psycopg2连接的最佳实践?

时间:2017-05-10 17:38:50

标签: python psycopg2

假设我有一个类来创建Redshift对象依赖项。我想创建一个连接,然后重新使用它进行许多不同的事务。

我应该在__init__函数中创建它,然后在self.conn.close()语句中设置__del__来模仿withtry/finally模型吗?< / p>

编辑: 以下是我提出的建议:

class DatabaseConn:
    def __init__(self, env: DBEnvironment = DBEnvironment.PROD):
        """
        A database connection that can be safely instantiated once, and then 
        passed around inside a class or between functions.

        :param env: The environment to connect to, choices are `DEV` and 
         `PROD`. 
        """
        self._conn = ppg2.connect(**env.value)

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

    def execute(
            self,
            query_or_stmt: str,
            has_res: bool = True) -> Optional[List[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 has_res: Whether or not results should be returned.

        :return: If `has_res` is `True`, then a list of tuples. 
        """
        cur = self._conn.cursor()
        cur.execute(query_or_stmt)
        if has_res:
            return cur.fetchall()

    def return_cursor(self):
        """
        :return: A psycopg2 cursor. 
        """
        return self._conn.cursor()

1 个答案:

答案 0 :(得分:1)

我建议避免使用 del 作为析构函数,因为它的调用模式是不确定的,并且根本不能保证它被调用。

如果要获得A = list(a = matrix(1:4, 2), b = matrix(2:5, 2)) B = matrix(3:6, 2) lapply(A, FUN = function(x) x %*% B) 资源with有界变体行为,可以使用as模块执行此操作。

contextlib

这个例子来自python docs:https://docs.python.org/3/library/contextlib.html

此方法的缺点是需要对资源的上下文进行编码。

另一种方法是编写一个真正的析构函数,当连接引用计数器达到0时将调用它。这与使用from contextlib import contextmanager @contextmanager def tag(name): print("<%s>" % name) yield print("</%s>" % name) >>> with tag("h1"): ... print("foo") ... <h1> foo </h1> 的原始想法非常相似,但是为了避免使用{{__del__的许多问题。 1}}直接使用weakref.finalize