[英]Best practice for re-using a psycopg2 connection in a class?
說我有一個創建Redshift對象依賴項的類。 我想創建一個連接,然后將其重新用於許多不同的事務。
我應該在__init__
函數中創建它,然后在__del__
語句中設置self.conn.close()
來模仿with
或try/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.