Neulich musste ich einige Daten aus einer Postgres-Datenbank sammeln, um mit ihnen zu arbeiten. Ich brauchte eine Liste von den IDs von allen Elementen in einer Tabelle, und ihren zugehörigen Namen. Mit diesen Daten wollte ich dann von Puppeteer ein PDF für jede ID erstellen lassen, und die Dateien mit dem Namen versehen.

Als Ausgangspunkt hätte ich also gerne ein JSON gehabt, damit ich es direkt in mein Node.js Script werfen kann, aber ich hatte keine Lust, mir für das einmalige Auslesen der IDs und Namen extra einen Datenbankzugriff mit dem pg Package oder so zu bauen. Hm! Was tun?

Glücklicherweise konnte ich dann herausfinden, dass Postgres eine eingebaute Funktion hat, die genau das macht: json_object_agg!

Angenommen, wir haben diese Tabelle:

id name username
1 Daniel danjel
2 Clara wundertaeter

Dann können wir die folgende Abfrage machen (ich mache meine Abfragen meistens in Postico), und Postgres aggregiert das direkt in ein JSON Object!

SELECT json_object_agg(
  "user".id,
  "user".username
) FROM "user";

Das Ergebnis sieht dann so aus:

{
  "1": "danjel",
  "2": "wundertaeter"
}

Mit psql geht das sogar direkt im Terminal:

psql --tuples-only -d lesetagebuch_dev \
  -c "SELECT
  json_object_agg(\"user\".id, \"user\".username)
  FROM \"user\";" | jq

Durch das --tuples-only werden Header und Footer von psql übersprungen, so dass das Ergebnis direkt in jq gepiped oder mit > data.json in eine Datei gespeichert werden kann.

Die Suche nach dieser Funktion hat vermutlich etwas länger gedauert, als eine CSV aus Postico zu exportieren, aber falls ich so etwas ähnliches irgendwann noch mal machen muss, geht es dafür viel schneller, und macht mehr Spaß. (Und damit ich es nicht vergesse, schreibe ich es auf!)