1


0

Pylons:SQLAlchemy MySQL接続を外部ライブラリと共有する

SQLAlchemyを使用してPylonsを実行してMySQLに接続しているため、コントローラーでデータベース接続を使用する場合、これを実行できます。

from myapp.model.meta import Session

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        rows = conn.execute('SELECT whatever')
...

コントローラーが外部ライブラリを呼び出す必要があり、データベース接続も必要であり、既に確立されているSQLAlchemy MySQL接続から接続を提供したいとします。

from myapp.model.meta import Session

import mymodule

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        myobject = mymodule.someobject(DATABASE_OBJECT)
        ...
        conn.close()

DATABSE_OBJECTはどうあるべきですか? 可能性:

  1. Session`を渡します-そして、 Session.connection() `を開いて閉じます モジュールコード

  2. 「conn」を渡し、コントローラーで「conn.close()」を呼び出します

  3. 接続パラメーターを渡すだけで、モジュールコードを設定できます 独自の接続

別のしわがあります。それは、 app_globals.py`でいくつかのオブジェクトをインスタンス化する必要があり、これらのオブジェクトもデータベース接続が必要であることです。 `app_globals.py`は Session`のSQLAlchemy接続をまだ使用できないようです-まだバインドされていません。

私のアーキテクチャは根本的に不健全ですか? このようにPylonsと外部ライブラリ間の接続を共有しようとするべきではありませんか? ありがとうございます。

2 Answer


2


接続を自分で管理すべきではありません-それはすべてSQLAlchemyによって行われます。 どこでもスコープ付きセッションオブジェクトを使用すれば、問題ありません。

def init_model(engine):
    sm = orm.sessionmaker(autoflush=False, autocommit=False, expire_on_commit=False, bind=engine)
    meta.engine = engine
    meta.Session = orm.scoped_session(sm)

def index(self):
    rows = Session.execute('SELECT ...')

Sessionオブジェクトを外部ライブラリに渡し、必要に応じてそこでクエリを実行できます。 .close()を呼び出す必要はありません。

app_globalsに関して、environment.pyからdbを初期化した後に呼び出されるglobalsクラスに他のメソッドを追加することで解決しました

class Globals(...):
    def init_model(self, config):
        self.some_persistent_db_object = Session.execute('...')

def load_environment(...):
    ...
    config['pylons.app_globals'].init_model(config)
    return config


1


_ DATABSE_OBJECTはどうあるべきですか? 可能性: _

  1. より高いレベルの抽象化インターフェースを持つ「プロキシ」または「ヘルパー」オブジェクトを渡す

外部ライブラリが本当にSQLAlchemyセッションに直接アクセスする必要がない限り、「execute(sql)」ではなく「get_account(account_no)」などのメソッドを持つオブジェクトを提供できます。 そうすることで、SQLAlchemy固有のコードがより分離された状態に保たれ、コードのテストも容易になります。

これは元の質問に対する答えではなく、デザインの提案であり、申し訳ありません。