データベースURIが時間とともに変化するWSGIの下でFlaskアプリを提供しています。URI は 2 時間ごとに別のデータベースに切り替わります。その時間を使って、一方のデータベースがいっぱいになり、もう一方のデータベースがアプリのデータを提供しています。
スイッチオーバーが発生したときに、クライアントが次の要求で正しい (異なる) データベースを取得できるように、セッションを構成する最善の方法を見つけるのに苦労しています。私のテストでは、最上位でデータベースを初期化すると、スイッチオーバーが発生したときに、クライアントはまだ古いデータベースを指しているままになります。
ページ (インデックスなど) 自体の内部にセッションを設定することも考えましたが、面倒です。また、あまりにも多くのデータベース接続を開いたり閉じたりして放置するのが心配です。起動時に両方のセッションを初期化し、各ページ内の切り替え時にどちらを使用するかを選択することで、おそらく機能させることができると思います。それは非効率的なようで、もっと良い方法があると確信しています。
ヘルプ?!
~~~~~~~~~~
これは私が現在行っていることの一般的な考え方ですが、リクエスト間で URI を変更する方法はありません。最上位コードは 1 回だけ、または頻繁に実行されます。
if now.hour % 2:
db_name = 'db1'
else:
db_name = 'db2'
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://foo:poo@localhost:3306/%s" % db_name
def init_db(uri, **kwargs):
engine = create_engine(uri, **kwargs)
Base.metadata.create_all(bind=engine)
global db_session
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base.query = db_session.query_property()
init_db(app.config['SQLALCHEMY_DATABASE_URI'], pool_recycle=3600)
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
@app.route('/')
def index():
...etc...
作業例 - 美しい。
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://foo:poo@localhost:3306/%s"
class SessionManager(object):
def __init__(self, base_uri=None, **kwargs):
self.session = None
self.base_uri = base_uri
self.kwargs = kwargs
def get_session(self):
if now.hour % 2:
db_name = 'db1'
else:
db_name = 'db2'
if self.session:
if self.session.name == db_name:
return self.session
else:
self.session.remove()
self.session = None
if not self.session:
engine = create_engine(self.base_uri % db_name, **self.kwargs)
db_session = scoped_session(sessionmaker(bind=engine))
db_session.name = db_name
self.session = db_session
return db_session
session_manager = SessionManager(base_uri=app.config['SQLALCHEMY_DATABASE_URI'], pool_recycle=3600)
db_session = LocalProxy(session_manager.get_session)