3

コンテキスト: 私は、SQLAlchemy ORM を使用して処理される DB、CherryPy で実行される Flask アプリに取り組んでいます。

問題:

アプリは正常に動作し、必要なことはすべて実行しますが、DB からデータを取得して表示するページがあり、「Ctrl + R」または「F5」を押したままにすると、つまり、ページを継続的に更新し、その数の DB 要求を行います。最初のいくつかはうまくいきますが、その後壊れます。次のエラーが記録されます。

(OperationalError) (2013, 'Lost connection to MySQL server during query')

Can't reconnect until invalid transaction is rolled back (original cause: 
InvalidRequestError: Can't reconnect until invalid transaction is rolled back)

This result object does not return rows. It has been closed automatically.

(ProgrammingError) (2014, "Commands out of sync; you can't run this command now")

気になる別のエラーもあります(ただし、今回は記録されていません)。

dictionary changed size during iteration

これは、辞書を作成するために取得した値を使用して、クエリを反復処理しているときに発生します。ディクショナリは、関数に対してローカル (dict のスコープ) です。

より詳しい情報:

セッションの処理方法:

ページに入ると新しいセッションが作成され、そのセッションを使用してすべての DB トランザクションが実行され、セッションは HTML をレンダリングする直前に閉じられます。つまり、技術的には、セッションのスコープは HTTP リクエストと同じです。

テーブル中またはテーブルsession.rollback()に例外が発生した場合にのみ実行します。いいえ、操作中はありません。ばかげた間違いを犯したか、正しい方法で物事を行っていないことは間違いありません。updatinginsertingrollback()query()

そのような無制限の更新は実際にはありそうなシナリオではありませんが、見逃すことはできません。また、同時に多くのユーザーが使用している場合も同様の動作になると思います。

SQLAlchemy エンジン、sessionmaker の処理方法:

sql_alchemy_engine = create_engine(self.db_string, echo=False, encoding="utf8", convert_unicode=True, pool_recycle=9)
sqla_session = sessionmaker(bind=sql_alchemy_engine)

SQLA ドキュメントで推奨されているように、一度だけ実行され、新しいセッションが作成され、sqla_session()必要に応じて返されます。

4

1 に答える 1

3

Flask を使用している場合は、flask-sqlalchemyを使用し、エンジンとセッションを手動で処理するのではなく、Flask リクエスト コンテキストでセッションを管理する必要があります。これは、SQLAlchemy が推奨する方法です。

ほとんどの Web フレームワークには、リクエストに関連付けられた単一のセッションを確立するためのインフラストラクチャが含まれています。このセッションは正しく構築され、リクエストの最後に対応する解体されます。このようなインフラストラクチャには、Flask Web フレームワークと組み合わせて使用​​する Flask-SQLAlchemy や、Pyramid および Zope フレームワークと組み合わせて使用​​する Zope-SQLAlchemy などの製品が含まれます。SQLAlchemy は、これらの製品を利用可能なものとして使用することを強くお勧めします。

http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html?highlight=flask

次に、次のように簡単にエンジンを作成します。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'your db uri'

db = SQLAlchemy(app)

または、アプリ ファクトリを使用している場合:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'your db uri'

    db.init_app(app)

これにより、使用する必要がある基本宣言モデルは at にdb.Modelなり、使用する必要があるセッションは at になりますdb.session

于 2013-11-07T14:12:49.420 に答える