sql >> データベース >  >> RDS >> Mysql

SQLalchemyの`yield_per()`の問題をよりよく理解する

    yield_per で使用しようとすると、問題のある読み込み戦略の両方で例外が発生します 、だからあまり心配する必要はありません。

    信じる subqueryloadの唯一の問題 2番目のクエリのバッチロードは(まだ)実装されていません。意味的には何も問題はありませんが、 yield_perを使用している場合 、おそらく、すべての結果を一度にロードしたくないという本当に正当な理由があります。そのため、SQLAlchemyはあなたの希望に反することを丁寧に拒否します。

    joinedload もう少し微妙です。これは、プライマリ行に複数の関連行がある可能性があるコレクションの場合にのみ禁止されています。クエリが次のような生の結果を生成するとします。ここで、AとBは異なるテーブルの主キーです:

     A | B 
    ---+---
     1 | 1 
     1 | 2 
     1 | 3 
     1 | 4 
     2 | 5 
     2 | 6 
    

    次に、 yield_per(3)を使用してこれらをフェッチします 。問題は、SQLAlchemyがフェッチする量をでしか制限できないことです。 、ただし、オブジェクトを返す必要があります 。ここでは、SQLAlchemyは最初の3行のみを参照するため、 Aを作成します。 キー1と3のオブジェクト B 子供:1、2、および3。

    次のバッチをロードするときに、新しい Aを作成する必要があります キー1のオブジェクト...ああ、しかしそれはすでにそれらの1つを持っているので、それを再度作成する必要はありません。追加のB 、4、失われます。 (つまり、 yield_perを使用して結合されたコレクションを読み取ることもできません。 安全ではありません—データのチャンクが失われる可能性があります。)

    「まあ、完全なオブジェクトができるまで行を読み続ける」と言うかもしれませんが、その Aの場合はどうでしょうか。 百人の子供がいますか?または百万? SQLAlchemyは、あなたが求めたことを実行できることを合理的に保証することはできません 正しい結果が得られるため、試行を拒否します。

    DBAPIは、任意の そのデータベースがすべてのDBAPI機能をサポートしていなくても、データベースは同じAPIで使用できます。 DBAPIはカーソルを中心に設計されていますが、MySQLには実際にはありません。 カーソル!代わりに、MySQL用のDBAPIアダプターはそれらを偽造する必要があります。

    したがって、 cursor.fetchmany(100) 動作します MySQLdb<から確認できます。 / code> ソースコード サーバーから遅延フェッチしないこと。すべてを1つの大きなリストにフェッチし、 fetchmanyを呼び出すとスライスを返します。 。

    psycopg2とは サポートは真のストリーミングであり、結果は永続的に記憶されます。 サーバー上で、Pythonプロセスは一度にそれらのいくつかしか認識しません。

    引き続きyield_perを使用できます MySQLdbを使用 、またはその他のDBAPI;これがDBAPIの設計の要点です。 DBAPIに隠されているすべての生の行(タプルであり、かなり安価)のメモリコストを支払う必要がありますが、またはかかりません。 すべてのORMオブジェクトに対して同時に支払う必要があります。



    1. 階層型MySQLクエリのヘルプが必要

    2. Microsoft Accessテーブルのヒント–秘訣とガイドラインパート4

    3. C#Windowsアプリケーションアクセスデータベースデータは閉じても保持されません

    4. mysql負荷テストツール