Python や Boo などの言語で LINQ のようなクエリを実行できますか?
-
02-07-2019 - |
質問
これを簡単に考えてみましょう C# LINQ 質問して想像してみてください db.Numbers
です SQL 1 列のテーブル Number
:
var result =
from n in db.Numbers
where n.Number < 5
select n.Number;
これは非常に効率的に実行されます C#, を生成するため、 SQL 次のようなクエリを実行します
select Number from Numbers where Number < 5
何それ しません することは選択することです 全て データベースから数値を取得し、フィルタリングします。 C#, 、最初はそうなるように見えます。
パイソン は同様の構文をサポートしています。
result = [n.Number for n in Numbers if n.Number < 5]
しかし、それは if
ここの句は、サーバー側ではなくクライアント側でフィルタリングを実行するため、効率が大幅に低下します。
同じくらい効率的なものはありますか リンク で パイソン?(現在評価中です パイソン 対 アイアンパイソン 対 ブー, したがって、これらの言語のいずれかで機能する答えで問題ありません。)
他のヒント
sqlスープ 明確な(っぽい)ワンライナーが必要な場合は、sqlalchemyでPythonで最も迅速な解決策が得られると思います。ページを見てください。
それは次のようなものであるはずです...
result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]
LINQ は、C# および VB.NET の言語機能です。これはコンパイラによって認識され、特別に扱われる特別な構文です。また、式ツリーと呼ばれる別の言語機能にも依存します。
式ツリーは、 少し 特別な構文ではないという点で異なります。これらは他のクラスのインスタンス化と同じように記述されますが、コンパイラーはラムダをランタイムのインスタンス化に変換することにより、内部で特別に処理します。 抽象構文ツリー. 。これらは実行時に操作して、別の言語でコマンドを生成できます(つまり、SQL)。
C# および VB.NET コンパイラは、LINQ 構文を受け取り、それをラムダに変換し、それを式ツリーのインスタンス化に渡します。さらに、これらのツリーを操作して SQL を生成するフレームワーク クラスが多数あります。「LINQ プロバイダー」を提供する他のライブラリ (MS 製およびサードパーティ製の両方) も見つかります。これは基本的に、別の AST プロセッサをポップインして、SQL 以外の LINQ から何かを生成します。
したがって、これらのことを別の言語で行う際の障害の 1 つは、ランタイム AST の構築/操作をサポートしているかどうかという問題です。Python や Boo の実装にそのような機能があるかどうかはわかりませんが、そのような機能については聞いたことがありません。
よく見てください SQLアルケミー. 。おそらくこれで、あなたが望むことのほとんどが実現できるでしょう。これにより、サーバー上で実行されるプレーンな古い SQL の Python 構文が提供されます。
LINQ の重要な要素は、式ツリーを生成するコンパイラの機能です。指定された Nemerle 式を Expression ツリー オブジェクトに変換する Nemerle のマクロを使用しています。次に、これを IQueryables の Where/Select/etc 拡張メソッドに渡すことができます。これは C# や VB の構文とは異なりますが、私にとっては十分近い構文です。
この投稿のリンクから Nemerle マクロを入手しました。http://groups.google.com/group/nemerle-dev/browse_thread/thread/99b9dcfe204a578e
Boo にも同様のマクロを作成できるはずです。ただし、サポートする必要がある式が多数あることを考えると、これはかなりの作業です。Ayende 氏はここで概念実証を行っています。http://ayende.com/Blog/archive/2008/08/05/Ugly-Linq.aspx