簡體   English   中英

在課程中重用psycopg2連接的最佳實踐?

[英]Best practice for re-using a psycopg2 connection in a class?

說我有一個創建Redshift對象依賴項的類。 我想創建一個連接,然后將其重新用於許多不同的事務。

我應該在__init__函數中創建它,然后在__del__語句中設置self.conn.close()來模仿withtry/finally模型嗎?

編輯:這是我想出的:

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()

我建議避免將del用作析構函數,因為它的調用模式是不確定的,並且不能保證完全被調用。

如果要獲取with資源as受限var行為,則可以使用contextlib模塊來實現。

from contextlib import contextmanager

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

>>> with tag("h1"):
...    print("foo")
...
<h1>
foo
</h1>

這個例子來自python docs: https : //docs.python.org/3/library/contextlib.html

這種方法的缺點是需要對資源的上下文進行編碼。

另一種方法是寫一個真實的析構函數時,連接引用計數器打0。這是非常相似你原來使用的想法將被調用__del__但要避免許多問題與使用__del__直接使用weakref.finalize

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM