PRQL: eine pipelinebasierte relationale Abfragesprache
(github.com/PRQL)- PRQL ist eine moderne Sprache zur Datentransformation und versteht sich als SQL-Alternative, die wie SQL gut lesbar, explizit und deklarativ ist
- Abfragen bestehen aus einer logischen Pipeline, in der jeder Transformationsschritt auf dem Ergebnis des vorherigen aufbaut; unterstützt werden zudem Abstraktionen wie Variablen und Funktionen
- PRQL wird zu SQL kompiliert, damit es mit jeder Datenbank verwendet werden kann, die SQL nutzt
- Sprachbeispiele verwenden Transformationen wie
from,filter,derive,group,aggregate,sortundtake, wobeifilterdie Rolle vonWHEREundHAVINGin SQL übernimmt - Zu den Syntaxfunktionen gehören eine eindeutige Datumsschreibweise, coalesce, Variablen, die auf andere Variablen verweisen, Python-ähnliche F-Strings, S-Strings zur Nutzung von SQL als Escape Hatch, eine Schreibweise für absteigende Sortierung sowie Bereichsausdrücke
- Angeboten werden der PRQL Playground für Experimente im Browser, das PRQL Book als Sprachdokumentation und prql-lang.org mit SQL-Vergleichen und Beispielen
- Stand Juni 2026 kann PRQL über unterstützte Integrationen oder Sprach-Bindings verwendet werden, es gibt jedoch noch einige Bugs und fehlende Funktionen, und der Vorbereitungsstand für den Einsatz in nichttechnischen Teams ist derzeit auf relativ einfache Abfragen beschränkt
- Der Entwicklungsschwerpunkt liegt auf Arbeiten an einem neuen Resolver, der Behebung vorrangiger Bugs, dem Schließen verbleibender Funktionslücken, damit es für die meisten Standard-SQL-Abfragen nutzbar wird, sowie auf dem Hinzufügen experimenteller Unterstützung für Module und Projekte mit mehreren Dateien
- Als Integrationspunkte werden eine VS Code extension, Jupyter integration, die QStudio-Integration, Jupyter magic, pyprql Docs und prqlc-js angeboten
- Das Repository besteht aus dem in Rust geschriebenen Compiler
prqlcund dem Web-Content-Bereichweb;prqlckompiliert PRQL zu SQL und umfasst eine CLI sowie Bindings für mehrere Sprachen
1 Kommentare
Hacker-News-Meinungen
Die Beispiele auf der Website https://prql-lang.org/ wirken wie der größte Vorteil von PRQL, insbesondere weil das erzeugte SQL sauber und intuitiv ist und so aussieht, als hätte man es selbst geschrieben.
Vor 10 bis 15 Jahren baute man neue Datenbanken wie Mongo, Riak oder Influx und überzeugte App-Entwickler, sie in neuen Projekten einzusetzen. Heute gibt es zunehmend konservativere Optionen wie EdgeDB, TimescaleDB oder PRQL, die Add-ons oder Query-Präprozessoren auf Postgres setzen, was die Einführung deutlich einfacher macht.
Schema und Migrationen bei Edge sind ebenfalls gut, aber die PRQL-Syntax ist intuitiver. In Anwendungscode gibt es bereits viele Daten-Transformations-Pipelines, etwa TypeScripts map/filter-Chains, Rust-Iteratoren, Ruby Enumerables, Java Streams, .NET LINQ und Rx in verschiedenen Sprachen, daher ist das Konzept sehr vertraut. Großartig ist, dass man aus PRQL gutes SQL erzeugen und speichern, es später prüfen, den Ausführungsplan ansehen und bei Bedarf Indizes hinzufügen kann.
Die Beispiele lassen SQL künstlich ausführlicher aussehen.
from employees / select {id, first_name, age} / sort age / take 10wirkt besser als ein über viele Zeilen verteiltesSELECT ... FROM ... ORDER BY ... LIMIT ..., aber echtes SQL kann man auch alsselect id, first_name, age from employees order by age limit 10schreiben. Statt geschweifter Klammern gibt es im Wesentlichen nur den Unterschied zwischenorder byundsort, also eher ein oder zwei Zeichen Unterschied.Dass man die Reihenfolge der Query-Abschnitte ändern kann, ist zwar etwas, worüber sich alle bei SQL beschweren, aber dafür kommen verschiedene Arten von Klammern, Doppelpunkte und andere Syntax ohne ersichtlichen Grund hinzu, und es scheint nichts zu leisten, was SQL nicht bereits kann. Ich frage mich, was der Reiz daran ist.
Wir haben kürzlich PRQL-Unterstützung in ClickHouse gemergt: https://github.com/ClickHouse/ClickHouse/pull/50686
Derzeit ist es noch eher experimentell, und es ist nicht sicher, ob es tatsächlich brauchbar oder nützlich sein wird. Es gibt auch einige Bedenken rund um Rust: https://github.com/ClickHouse/ClickHouse/issues/52053#issuecomment-1643805521
Ich hoffe, dass PRQL stark wächst und zu einer erstklassig unterstützten Sprache in Postgres wird. Relationenalgebra ist schön, aber SQL ist ein unbeholfener Erstentwurf, der schon vor Jahrzehnten hätte ersetzt werden sollen.
Selbst Codd war mit SQL unzufrieden. Was er erfunden hat, ist erstaunlich, aber seitdem haben wir viel über Programmiersprachen-Design gelernt.
ORDER BYdas aufbricht.Das zeigt sich daran, dass die Sortierung einer Relation verschwindet, wenn man sie in eine Unterabfrage einbettet, was ziemlich unerwartet ist. Das Datenmodell von PRQL ist dem relationalen Modell sehr ähnlich; der große Unterschied ist, dass Relationen als Arrays von Tupeln definiert sind und damit eine Reihenfolge haben. Ich hoffe, dass PRQL als „relationale Sprache Mk II“ bekannt wird.
Es gibt auch ein DBeaver-Plugin [3], bei dem Dokumentation und Vereinfachung der Nutzung noch ausgebaut werden müssen, aber auch damit könnte es möglich sein, Postgres mit PRQL abzufragen. Und schließlich kann man mit pyprql [4] Postgres aus einem Jupyter Notebook heraus abfragen.
[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
Zur Einordnung: Ich bin PRQL-Contributor.
Damals dachte ich, es liege daran, dass ich noch nicht genug wusste, um zu verstehen, warum es so sein müsse. Heute weiß ich, dass es keinen Grund dafür gibt. SQL ist wie eine natürliche Sprache geworden: Selbst wenn etwas keinen Sinn ergibt, kann man es nicht widerlegen, man muss es einfach so sagen. Aber SQL ist keine natürliche Sprache, und wir können es besser machen.
Wenn die Hauptbeschwerde an SQL darin besteht, dass man die Reihenfolge von
SELECT,FROM,WHEREnicht ändern kann, ist es für eine in den 70ern entworfene Sprache ziemlich okay.Umgekehrt wirkt PRQL syntaktisch voller willkürlichem Rauschen. Ich sehe nicht, warum ich
join side:left p=positions (p.id==employees.employee_id)besser finden sollte alsLEFT JOIN positions AS p ON p.id = employees.employee_id.Die Art, wie bei PRQL von oben nach unten jeder Schritt eine Transformation des vorherigen ist, ergibt deutlich mehr Sinn. Für SQL braucht man ein Nachschlagewerk, während PRQL sich so anfühlt, als würde man genau hinschreiben, was die Query tun soll. Allerdings ist die Join-Syntax von PRQL sehr schlecht; explizite Keywords wie
left joinhätten beibehalten werden sollen, und Aliasse sowie Abkürzungen für Join-Spalten hätte man besser gestalten können.Erstens kann man innerhalb desselben
selecteine zuvor ausgewählte Spalte später nicht wiederverwenden. Man kann nichtgnarly_calculation AS some_valueund danachsome_value * 2 AS some_value_doubledschreiben, sondern muss das in eine Subquery packen. Zweitens kann man nicht alle Spalten außer bestimmten Spalten angeben. Wenn man Zwischenberechnungen aus einer Subquery hochziehen muss, sie aber in der finalen Ausgabe nicht braucht, kann man nicht so etwas wie* EXCEPT some_valuesagen, sondern muss alle gewünschten Ausgabespalten einzeln auflisten.Das gewählte Beispiel ist vielleicht ein Fall, in dem Klammern und Kommata sehr helfen würden, aber im Kontext der gesamten Sprache ist es nicht so schlimm.
:wird konsistent wie ein Keyword-Argument verwendet, und=scheint für Aliasse genutzt zu werden.joinist und das erste Wort der Anweisungjoinlautet, wird klarer, was die eigentliche Operation ist.Auch als allgemeines Beispiel für Funktionsaufrufe ist
foo(bar)besser als „bar to foo()“.PRQL 0.9 wurde gerade erst vor ein paar Stunden veröffentlicht, also gutes Timing. Die Release Notes gibt es hier: https://github.com/PRQL/prql/releases/tag/0.9.0
Es gibt eine ziemlich große Breaking Change: Die Tupel-Syntax wechselt von
[]zu{}. Anfangs sahen diese Dinge wie Listen aus, aber mit der Zeit wurde klar, dass es tatsächlich Tupel sind. Wie in den Release Notes erwähnt, kann bald Array-Unterstützung beginnen, wenn[]frei bleibt. Zur Einordnung: Ich bin PRQL-Contributor.Eine Grenze von PRQL ist, dass es per Design nur SELECT unterstützt. Wenn man Daten einfügen/ändern/löschen will, muss man wieder zu SQL zurück.
Der Data Scientist im Team kann zwar Queries in PRQL liefern, aber um sie in eine echte Datenpipeline zu übernehmen, muss man sie in SQL übersetzen. Schön wäre zumindest eine begrenzte Funktionalität wie das Einfügen in eine neue temporäre Tabelle. Zum Beispiel in der Form
from tracks / filter artist == "Bob Marley" / save bob_marley_tmp.insert/update/delete, die am Ende der Pipeline stehen müssen und einen Tabellennamen als Argument bekommen.SQL wie
UPDATE counters SET value = value + 1 WHERE name LIKE 'prefix.%'könnte man in PRQL etwa alsfrom counters / filter startswith(name, 'prefix.') / derive { new_value = value + 1 } / select { name, new_value } / update countersschreiben.Der unvermeidliche Artikel dazu: „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
Das Ziel von PRQL ist es, eine gute Sprache zu sein, die sich gut integrieren lässt und auf der man aufbauen kann. Wir wollen nicht N Sprachen für N Datenbanken entwickeln. PRQL wird immer Open Source sein und kein kommerzielles Produkt daraus machen, daher halte ich es für deutlich realistischer als datenbank- oder produktspezifische Sprachen. Ich bin PRQL-Entwickler.
Früheres Show HN: https://news.ycombinator.com/item?id=31897430
„Show HN: PRQL 0.2 – a better SQL“ wurde am 27. Juni 2022 von maximilianroos gepostet und hatte 378 Punkte sowie 161 Kommentare.
Der ursprüngliche Vorschlag: https://news.ycombinator.com/item?id=30060784
„PRQL – A proposal for a better SQL“ wurde am 24. Januar 2022 von maximilianroos gepostet und hatte 650 Punkte sowie 295 Kommentare.
Erinnert mich an Microsofts KQL: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/
Die Syntax ist nicht besonders wichtig; entscheidend ist, was der Optimizer macht.
Viele heutige SQL-Probleme wirken wie Altlasten. Weil frühere Engines mit moderner Syntax nicht gut umgehen konnten, wurden viele darauf trainiert, schwer lesbare, komplexe und tief verschachtelte Queries zu schreiben. Bei Common Table Expressions (CTEs) wurden sie zum Beispiel sofort materialisiert, und deshalb wucherten alte Stile wie
SELECT FROM (SELECT FROM (SELECT FROM A JOIN (SELECT ) B ON A.x=B.x))).Durch Verbesserungen beim CTE-Handling der Engines wird es zunehmend einfacher, verständliche und kombinierbare Queries wie
WITH A AS (...), WITH B AS (...), WITH C AS (SELECT y FROM A) SELECT result FROM C WHERE ...zu schreiben. Mit modernen Window Functions,SELECT * EXCEPTund komplexeren Funktionen wieTOP X FOLLOWINGkann SQL noch einfacher werden.In so einem Umfeld sehe ich nicht, dass kleine Verbesserungen einer anderen Syntaxform wie PRQL großen Nutzen bringen. Man kann es zwar in eine Pipeline umschreiben, die wie imperativer Code aussieht, aber der Optimizer kann Teile davon auch verwerfen. Es stimmt, dass SQL in manchen Punkten besser werden sollte, aber überzeugende Gründe für äußerliche oder syntaktische Unterschiede habe ich bisher nicht gesehen.