2017-05-10 16 views
0

Redshiftオブジェクトの依存関係を作成するクラスがあります。私は1つの接続を作成し、それをさまざまなトランザクションに再利用したいと考えています。クラス内でpsycopg2接続を再利用するためのベストプラクティス?

私はそれが__init__機能で作成し、次にwithまたはtry/finallyモデルを模倣する__del__文でself.conn.close()を設定すべきか?

編集:私はパターンが非決定的で呼び出していますので、デルデストラクタとしてを避けることをお勧めし

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

、すべてで呼ばれることが保証されていません。ここに は、私が思い付いたものです。

withリソースasの制限付きの動作を取得するには、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のドキュメントから来る:https://docs.python.org/3/library/contextlib.html

この方法の欠点は、あなたのリソースのコンテキストがコード化する必要があるということです。

代替はweakref.finalizeを使用し、接続の参照カウンタが0これは直接__del__を使用して問題の多くを回避するために、__del__を使用しますがあなたのオリジナルのアイデアとかなり類似しているに当たったときに呼び出される本当のデストラクタを書くことです。

+0

私が思いついたコードを追加しました。 'weakref.finalize'関数はオブジェクトの限定されたメソッドをとることができません。そのため、' close'メソッドが呼び出されるように接続自体を渡す方法はありません。この周りのどのような方法でも見ることができますか? – flybonzai

関連する問題