PRQL: パイプライン化されたリレーショナルクエリ言語
(github.com/PRQL)- PRQLは、データを変換するためのモダンな言語であり、SQLのように読みやすく、明示的で宣言的なSQL代替言語を目指している
- クエリは、変換ステップが前の結果を引き継ぐ論理パイプラインで構成され、変数や関数のような抽象化をサポートする
- SQLを使用するあらゆるデータベースと併用できるよう、PRQLをSQLへコンパイルする
- 言語例では、
from、filter、derive、group、aggregate、sort、takeのような変換を使用し、filterはSQLのWHEREとHAVINGの役割を置き換える - 構文機能として、明確な日付表記、coalesce、他の変数を参照する変数、Pythonに似たF-string、SQLをescape hatchとして使うS-string、降順ソート表記、範囲式を提供する
- ブラウザで試せる PRQL Playground、言語ドキュメントである PRQL Book、SQL比較と例を提供する prql-lang.org を提供している
- 2026年6月時点では、対応する統合やサポート対象の言語バインディングを通じて利用できるが、一部のバグや未実装機能が残っており、非技術チーム向けに展開できる準備範囲はかなり単純なクエリに限られている
- 開発の焦点は、新しいresolverの作業、優先度の高いバグ修正、標準的なSQLクエリの大半で使えるように残る機能差分を埋めること、そしてモジュールおよび複数ファイルプロジェクトへの実験的サポート追加にある
- 統合ポイントとして、VS Code extension、Jupyter integration、QStudio integration、Jupyter magic、pyprql Docs、prqlc-js を提供している
- リポジトリは、Rustで書かれたコンパイラ
prqlcとWebコンテンツ領域webで構成され、prqlcはPRQLをSQLへコンパイルし、CLIと複数の言語バインディングを含む
1件のコメント
Hacker Newsの意見
ウェブサイト https://prql-lang.org/ の例がPRQLの最大の強みに見え、特に生成されるSQLがきれいで直感的で、自分で直接書いたような形になっている
10〜15年前はMongo、Riak、Influxのような新しいデータベースを作り、アプリ開発者に新プロジェクトで使うよう説得していたが、最近はEdgeDB、TimescaleDB、PRQLのように Postgresにアドオンやクエリ・プリプロセッサを載せる保守的な選択肢が増えており、ずっと導入しやすい
Edge側のスキーマとマイグレーションも良いが、PRQLの構文のほうがより直感的。TypeScriptのmap/filterチェーン、Rustのイテレータ、Rubyのenumerable、Java stream、.NET LINQ、さまざまな言語のRxのように、アプリケーションコードにはすでに データ変換パイプラインが多くあり、概念として非常になじみ深い。PRQLから良いSQLを生成して保存し、あとで確認し、実行計画を見て、必要な場所にインデックスを追加できる点が素晴らしい
例はSQLを恣意的に冗長に見せている。行を多く分けた
SELECT ... FROM ... ORDER BY ... LIMIT ...よりfrom employees / select {id, first_name, age} / sort age / take 10のほうが良く見えるが、実際のSQLもselect id, first_name, age from employees order by age limit 10のように書けるし、中かっこがない代わりにorder byとsortの違い程度なので、1〜2文字の違いに近いクエリの区画の順序を変えられる点は、誰もがSQLに対して不満を言う部分だが、その代わりに複数種類の括弧、コロン、その他の構文が理由もなく入っており、SQLがすでにできないことを特に実現しているようにも見えない。魅力的なポイントが何なのか気になる
最近ClickHouseに PRQLサポートをマージした: https://github.com/ClickHouse/ClickHouse/pull/50686
まだ実験に近く、実用に足るものか、有用かどうかははっきりしない。Rust関連の懸念も少しある: https://github.com/ClickHouse/ClickHouse/issues/52053#issuecomment-1643805521
PRQLが大きく成長して、Postgresの 第一級サポート言語になってくれるといい。関係代数は美しいが、SQLは何十年も前に置き換えられているべきだった粗い一次設計だ
CoddでさえSQLに不満を持っていた。彼が発明したものは驚くべきものだが、その後、私たちはプログラミング言語設計について多くを学んだ
ORDER BYで壊すなど、いくつもの点でずれているこの問題はサブクエリで包むと関係の並び順が消える、といった形で現れるが、かなり予想外だ。PRQLのデータモデルは関係モデルと非常によく似ており、大きな違いは関係が タプル配列として定義され、順序を持つ点だ。PRQLが「関係型言語 Mk II」として知られるようになることを期待している
DBeaverプラグイン [3] もあるが、ドキュメント化と使いやすさの簡素化がさらに必要だ。それでも、これでPostgresをPRQLでクエリできる可能性がある。最後にpyprql [4] を使えば、Jupyter notebookからPostgresをクエリできる
[1]: https://github.com/ywelsch/duckdb-prql
[2]: https://duckdb.org/docs/extensions/postgres_scanner.html
[3]: https://github.com/PRQL/prql/issues/1643
[4]: https://github.com/PRQL/pyprql
ちなみにPRQLコントリビューターです
当時は、なぜそうでなければならないのかを理解できるほど十分に分かっていないからだと思っていたが、今ではそんな理由はないと分かっている。SQLは自然言語のようになってしまっていて、筋が通らなくても反論できず、ただそう言うしかない。しかしSQLは自然言語ではなく、もっと良くできる
SQLに対する主な不満が、
SELECT、FROM、WHEREの順序を変えられないことだというなら、70年代に設計された言語としてはかなりよくできているほうだと思う。逆にPRQLは、構文に恣意的なノイズが多いように見える。なぜ
join side:left p=positions (p.id==employees.employee_id)をLEFT JOIN positions AS p ON p.id = employees.employee_idより好むべきなのか分からない。PRQLのように、上から下へ各ステップが前のステップの変換になる方式のほうがずっと筋が通っている。SQLにはリファレンスマニュアルが必要だが、PRQLはクエリにさせたいことをそのまま書いている感覚がある。ただしPRQLのjoin構文は非常に悪く、明示的な
left join系のキーワードを維持すべきだったし、エイリアスや結合カラムの省略記法ももっとよくできたはずだ。1つ目は、同じ
selectの中で前に選択したカラムを後ろで使えないこと。gnarly_calculation AS some_valueの後にsome_value * 2 AS some_value_doubledのようには書けず、サブクエリで包まなければならない。2つ目は、特定のカラムだけを除いた全カラムを指定できないこと。中間計算をサブクエリから引き上げる必要があるが最終出力には不要なとき、* EXCEPT some_valueのようには言えず、欲しい出力カラムをすべて列挙しなければならない。選ばれた例は、括弧とカンマが大いに役立つケースかもしれないが、言語全体の文脈ではそこまで悪くない。
:は一貫してキーワード引数のように使われ、=はエイリアスに使われているようだ。join演算の引数になり、文の最初の語がjoinなので実際の演算が何なのかより明確になるからだ。一般的な関数呼び出しの例でも、
foo(bar)のほうが “bar to foo()” よりよい。PRQL 0.9が数時間前にリリースされたばかりなので、タイミングがよい。リリースノートはここで見られる: https://github.com/PRQL/prql/releases/tag/0.9.0
タプル構文が
[]から{}に変わる、かなり大きな破壊的変更がある。当初はこれらがリストのように見えていたが、時間が経つにつれて実際にはタプルだと分かったためだ。リリースノートのとおり、[]を空けておけば、近いうちに配列サポートを始められる。ちなみにPRQLのコントリビューターです。PRQLの限界は、設計上SELECTのみ対応している点だ。データを挿入/変更/削除するには、またSQLに戻らなければならない。
チームのデータサイエンティストがPRQLでクエリを渡すことはできるが、実際のデータパイプラインに入れるにはSQLに翻訳する必要がある。少なくとも新しい一時テーブルに挿入する程度の限定的な機能でも対応してくれるとよい。例えば
from tracks / filter artist == "Bob Marley" / save bob_marley_tmpのような形だ。insert/update/delete演算子を用意し、テーブル名を引数に取らせればよい。UPDATE counters SET value = value + 1 WHERE name LIKE 'prefix.%'のようなSQLは、PRQLではfrom counters / filter startswith(name, 'prefix.') / derive { new_value = value + 1 } / select { name, new_value } / update countersのように書けるはずだ。ここで外せない記事: “I don't want to learn your garbage query language” [1]
[1] https://erikbern.com/2018/08/30/i-dont-want-to-learn-your-garbage-query-language.html
PRQLの目標は、統合し、その上に構築しやすい優れた言語になることだ。N個のデータベースにN個の言語を作りたいわけではない。PRQLは常にオープンソースであり、商用製品を作るつもりはないので、データベース別・製品別の言語よりはるかに実現可能だと見ている。PRQL開発者です。
以前のShow HN: https://news.ycombinator.com/item?id=31897430
“Show HN: PRQL 0.2 – a better SQL” は2022年6月27日にmaximilianroosが投稿し、378ポイント、コメント161件だった。
最初に提案された元投稿: https://news.ycombinator.com/item?id=30060784
“PRQL – A proposal for a better SQL” は2022年1月24日にmaximilianroosが投稿し、650ポイント、コメント295件だった。
MicrosoftのKQLを思い出す: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/
構文はそれほど重要ではなく、重要なのはオプティマイザが何をするかである
現在のSQLの問題の多くは、古い荷物のように見える。昔のエンジンが現代的な構文をうまく処理できなかったため、多くの人が読みにくく複雑で、深くネストしたクエリを書くように訓練されてきた。たとえば共通テーブル式(CTE)はすぐに実体化してしまうようなものだったので、
SELECT FROM (SELECT FROM (SELECT FROM A JOIN (SELECT ) B ON A.x=B.x)))のような古いスタイルが横行していたエンジンのCTE処理改善のおかげで、
WITH A AS (...), WITH B AS (...), WITH C AS (SELECT y FROM A) SELECT result FROM C WHERE ...のような理解しやすく組み合わせ可能なクエリを書くことが、ますます容易になっている。現代的なウィンドウ関数、SELECT * EXCEPT、より複雑なTOP X FOLLOWINGのような機能が加われば、SQLはさらにシンプルになり得るこうした環境では、PRQLのような別の構文形式による小さな改善が大きな利益をもたらすとは思わない。命令型に見えるパイプラインとして書き直すことはできるが、オプティマイザはその一部を捨てるかもしれない。SQLでもっと改善すべき点があるのは確かだが、見た目や構文上の違いについて、説得力のある根拠はまだ見ていない