web-dev-qa-db-ja.com

私のフラスコ-sqlalchemy削除クエリが失敗するのはなぜですか

ティッカーがリストの1つに一致するデータベースからすべての株を削除したいフラスコsqlalchemyを使用するクエリがあります。これは私が現在持っているクエリです:

Stock.query.filter(Stock.ticker.in_(new_tickers)).delete()

どこ new_tickersは、有効なティッカーのstrのリストです。

私が得ているエラーは次のとおりです:

sqlalchemy.exc.InvalidRequestError: Could not evaluate current criteria in Python: "Cannot evaluate clauselist with operator <function comma_op at 0x1104e4730>". Specify 'fetch' or False for the synchronize_session parameter.
12
user5948213

私はこの質問への答えを探してここに来ました(これは最初のGoogleヒットでした)。 @ScottLeeの答えは私を正しい情報に導きます。彼の解決策はオプションですが、影響は説明されていません。

基本的に、SQLAlchemyは、さまざまなSQLAlchemyメソッドを発行するときに、セッションをPythonで維持します。エントリを削除すると、SQLAlchemyはセッションから削除された行をどのように削除しますか?これは、deleteメソッドのパラメータによって制御されます。 、「synchronize_session」。synchronize_sessionには次の3つの可能性があります。

  • 'evaluate':生成されたクエリをPythonで直接評価して、セッションから削除する必要があるオブジェクトを決定します。これがデフォルトです非常に効率的ですが、堅牢ではなく、複雑なクエリを評価できません。クエリを評価できない場合は、sqlalchemy.orm.evaluator。UnevaluatableError条件が発生します。
  • 'fetch':削除の前に選択クエリを実行し、その結果を使用して、セッション内のどのオブジェクトを削除する必要があるかを判断します。これはそれほど効率的ではありませんが(潜在的にはるかに効率的ではありません)、有効なクエリを処理できます
  • False:これはセッションの更新を試みないため、非常に効率的ですが、削除後もセッションを継続して使用すると、不正確な結果が得られる可能性があります。

どちらのオプションを使用するかは、コードでのセッションの使用方法に大きく依存します。複雑なクエリに基づいて行を削除する必要があるほとんどの単純なクエリでは、Falseが適切に機能します。 (質問の例はこのシナリオに適合します)

SQLAlchemy Deleteメソッドリファレンス

7
TheDavidFactor

このコードで試してください:

Stock.query.filter(Stock.ticker.in_(new_tickers)).delete(synchronize_session=False)

https://docs.sqlalchemy.org/en/latest/orm/query.html?highlight=delete#sqlalchemy.orm.query.Query.delete

3
ScottLee