Die PostgreSQL Erweiterung pg_parquet macht Copy from/Copy to Parquet für lokale Dateien und für S3 und wohl bald auch für Azure. Wie Ralph schon gesagt hat, ist diese Erweiterung nicht für direkte Abfragen darauf geeignet. Nur indirekt, indem man die damit erzeugten Tabellen abfragt.
Ich muss feststellen, dass mein Blogpost mit „neu“ im Titel etwas voreilig war. Denn erstens kann PostgreSQL schon lange Parquet-Dateien lesen(!) und zweitens ist das erwähnte pg_parquet ziemlich eingeschränkt. Der einzige Vorteil von pg_parquet scheint mir zu sein, dass es Parquet schreiben kann.
Was es schon lange für PostgreSQL gibt, sind sogenannte „Foreign Data Wrappers“ (FDW): Siehe Foreign data wrappers - PostgreSQL wiki. FDW ist seit über 20 Jahren Teil des SQL-Standards (SQL/MED). Es regelt den Zugriff auf „entfernte Objekte“. SQL/MED kennen leider viel zu wenige Leute (vor allem die SPARQL-RDF-Fans nicht). Deshalb zähle ich es zu „modernem SQL“.
In PostgreSQL gibt es zum Lesen von Parquet-Dateien v.a. parquet_s3_fdw (Repo:parquet_s3_fdw) und pgsql-ogr-fdw (Repo: pgsql-ogr-fdw). pgsql-ogr-fdw ist nicht so gut optimiert wie parquet_s3_fdw, kann aber dafür GeoParquet und viele andere GIS-Formate lesen.
Um nun ein FDW in PostgreSQL anzusprechen, sind - ganz nach Standard SQL - drei Schritte notwendig - hier am Beispiel von parquet_fdw, gegeben die Parquet-Datei „/path/to/directory/userdata1.parquet“ (und gegeben die Extension ist installiert):
Schritt 1. Eine Serververbindung mit der externen Quelle erstellen („Server“ steht hier auch für Datei):
CREATE SERVER parquet_srv FOREIGN DATA WRAPPER parquet_s3_fdw;
Schritt 2: Erstellen einer „Benutzerzuordnung“, d.h. Benutzername/Passwort zu einem existierenden PostgreSQL-Benutzer (falls notwendig):
CREATE USER MAPPING FOR CURRENT_USER SERVER parquet_srv
OPTIONS (user 'postgres');
Schritt 3: Import des „fremden Schemas“ ins Schema public und Umbenennen der Tabelle in userdata (um Konflikte zu vermeiden):
IMPORT FOREIGN SCHEMA "/path/to/directory" LIMIT TO (userdata1)
FROM SERVER parquet_srv INTO public
OPTIONS (filename_pattern 'userdata1.parquet', table_name 'userdata');
– Nun die Abfrage:
SELECT * FROM userdata LIMIT 5;
Tipp: Wenn es also um das Lesen von GeoParquet geht, empfehle ich pgsql-ogr-fdw und wenn es um das optimierte Lesen von Parquet geht, empfehle ich parquet_fdw. Zum Schreiben könnte man pgsql-ogr-fdw oder besagtes pg_parquet nehmen.
Zum Schluss: Durch die Diskussion mit Ralph realisiere ein zunehmendes Interesse am direkten, optimierten Lesen von Dateien (Parquet, CSV) aus folgenden Gründen:
- Keine Datenverschiebung: Zugriff auf externe Daten (DBMS, Dateien) ohne diese physisch in die Datenbank zu verschieben.
- Datenintegration: Kombiniert Daten aus mehreren Quellen, einschliesslich externer Quellen, in einer einzigen Abfrage.
- Performance: (Cloud) Optimierte Performance für den Zugriff - insbesondere wenn es sich um ein DBMS oder Parquet oder Arrow handelt (nicht CSV).
Der Performance-Gewinn von Parquet geht jedoch zulasten der Ressourcen auf Datenanbieter-Seite zur Erzeugung dieses kolonnen-orientierten Formats.
P.S. Die Implementierung von DuckDB vom „Reading Parquet Files“ sowie allgemein erscheint mir je länger je mehr etwas „hacky“; read_parquet ignoriert die Benutzerzuordnung und allgemein weicht es oft unnötig vom SQL-Standard ab - wahrscheinlich um den Programmierern zu gefallen
. Wichtig ist einfach zu wissen, dass DuckDB für „Single-User“- und PostgreSQL für „Multi-User“-Betrieb konzipiert ist.