1

SQLAlchemy を使用してデータベースと対話するためのライブラリを作成しています。autoload_with=engineSQLAlchemy の機能がとても気に入っています。Tableコンストラクターに渡して、プログラマーが明示的に定義しなくても、テーブルのすべての列を取得できます。

「something」という名前のテーブルの基本的なアプローチは次のとおりです。

Base = declarative_base()
engine = create_engine('mysql://user:pass@host/db_name')
table = Table('something', Base.metadata, autoload_with=engine)

class Something(Base):
    __table__ = table

ただし、(異なるホスト上に) データベースの複数のバージョンがあるため、実行時にエンジンをパラメーターとして渡す必要があります。モジュールでこのようなものを書くという考えはちょっと嫌いですが、より良いアプローチをブランクにしています:

Base = declarative_base()
Something = None   # gets defined after initialize() is called

def initialize(engine):
    table = Table('something', Base.metadata, autoload_with=engine)
    class _Something(Base):
        __table__ = table

    global Something
    Something = _Something

そして、クライアント コードは、SQLAlchemy モデルを使用する前に、次のようなやっかいなことをしなければなりません。

import custom_db_api

engine = create_engine(...)
custom_db_api.initialize(engine)

外部の呼び出し元によるこの種のモジュールの初期化を処理するためのより良い方法はありますか?

4

1 に答える 1

0

engineさて、変数をcustom_db_apiモジュールに渡す方法を見つける必要があります。これはわずかにきれいかもしれません...

Base = declarative_base()

class Something(Base):
    pass

def initialize(engine):
    Something.__table__ = Table('something', Base.metadata, autoload_with=engine)

...または、のような「グローバル」から正しいエンジン初期化パラメーターを推測できる場合はsys.argv、次のようなものを使用できます...

import sys

Base = declarative_base()
if len(sys.argv) > 1 and sys.argv[1] == '--use-alt-db':
    engine = create_engine('mysql://user:pass@alt_host/db_name')
else:
    engine = create_engine('mysql://user:pass@main_host/db_name')

table = Table('something', Base.metadata, autoload_with=engine)

class Something(Base):
    __table__ = table

それは、使用するDBをプログラムにどのように伝えるかによって異なります。

于 2013-05-31T18:02:09.203 に答える