Zum Hauptinhalt springen
Data Operations · Endpunkte

PostgreSQL CSV API

Der Node registriert in Node-RED die Route GET /api/opendata/v1/:model.csv und liefert darüber Datensätze aus PostgreSQL als CSV-Datei aus. Welche Schemata, Tabellen und Spalten veröffentlicht werden, legen Sie in einem Modellregister fest; die Datenbankverbindung liegt in einem eigenen Konfigurationsnode. Der Node ist für Open-Data-Angebote gedacht, bei denen ein API-Gateway wie APISIX den öffentlichen Zugang übernimmt.

  • Open Data
  • CSV
  • HTTP-Endpunkt
Node-Typ
postgresql-csv-api (Konfigurationsnodes: postgresql-csv-api-registry, postgresql-csv-api-connection)
Paket
@htag/node-red-contrib-hypertegrity-endpoints
Eingänge / Ausgänge
0 / 0
Ziel
PostgreSQL (optional mit PostGIS)

Wofür Sie den Node verwenden​

Kommunen stellen Messdaten ihrer Datenplattform häufig als Open Data bereit. Der PostgreSQL-CSV-API-Node macht Tabellen der Plattformdatenbank, zum Beispiel die zeitliche Datenhaltung des Context Brokers, als CSV-Download zugänglich, ohne dass Sie eigene SQL-Abfragen oder HTTP-Nodes pflegen müssen.

Typische Einsatzfälle sind:

  • Monatliche Messreihen veröffentlichen: Wetter-, Pegel- oder Luftqualitätsdaten eines Monats als CSV für ein Open-Data-Portal.
  • Jahresdatensätze bereitstellen: Jährlich aggregierte Tabellen mit einem einzigen Aufruf pro Jahr abrufbar machen.
  • Sensible Spalten und Geräte ausnehmen: Einzelne Spalten oder entity_id-Werte werden vom Export ausgeschlossen, Spaltennamen für die Öffentlichkeit umbenannt.

So funktioniert der Node​

1

Route registrieren

Beim Deploy registriert der Node GET /api/opendata/v1/:model.csv am HTTP-Server von Node-RED und holt sich Modelle und Verbindung aus dem Modellregister.

2

Anfrage prüfen

Der Modellname aus der URL wird im Register nachgeschlagen; nur aktive Modelle werden bedient. Zeitparameter month oder year werden validiert.

3

Datenbank abfragen

Eine parametrisierte SELECT-Abfrage liest die Zeilen des gewünschten Zeitraums, schließt Entity-IDs aus und ergänzt bei Bedarf PostGIS-Koordinaten.

4

CSV ausliefern

Ausgeschlossene Spalten werden entfernt, Header umbenannt und die Datei als Download mit Content-Type text/csv gesendet.

Ergebnis: Eine CSV-Datei pro Modell und Zeitraum, live aus PostgreSQL erzeugt, ohne Zwischenspeicherung.

Der Node ist anfragegetrieben: Er hat keine Ein- oder Ausgänge im Flow und wird ausschließlich durch HTTP-Anfragen aktiv. Pro Node-RED-Instanz kann die Route nur einmal registriert werden; ein zweiter Node desselben Typs meldet einen Fehler. Die Datenbankabfrage findet bei jeder Anfrage statt.

Konfiguration​

Die Konfiguration verteilt sich auf drei Nodes: den Konfigurationsnode PostgreSQL CSV API: Verbindung, den Konfigurationsnode PostgreSQL CSV API: Modellregister und den eigentlichen Node PostgreSQL CSV API.

PostgreSQL CSV API: Verbindung (postgresql-csv-api-connection)​

FeldTypStandardBedeutung
NameTextleerAnzeigename; sonst <Host>:<Port>/<Datenbank>.
HostText${DB_HOST}Hostname oder IP des PostgreSQL-Servers. Platzhalter der Form ${VAR} werden aus der Umgebung aufgelöst; leer bedeutet die Umgebungsvariable DB_HOST.
PortZahl5432Port des Servers; leer bedeutet DB_PORT, sonst 5432.
DatenbankText${DB_NAME}Name der Datenbank; leer bedeutet DB_NAME.
BenutzerText (Credential)leerDatenbankbenutzer, verschlüsselt in flows_cred.json; leer bedeutet DB_USER.
PasswortPasswort (Credential)leerPasswort, verschlüsselt gespeichert; leer bedeutet DB_PASSWORD.

Der Verbindungspool (maximal 10 Verbindungen, Verbindungs-Timeout 10 s, application_name = node-red-postgresql-csv-api) wird beim ersten Zugriff angelegt und von allen Nodes geteilt, die diese Verbindung referenzieren. Die Verbindung zur Datenbank erfolgt ohne SSL.

PostgreSQL CSV API: Modellregister (postgresql-csv-api-registry), Registerkarte Datenbank​

FeldTypStandardBedeutung
NameTextleerAnzeigename des Registers.
PostgreSQLKonfigurationsnodekeinerVerbindung für Export und Editor-Abfragen. Ohne Auswahl werden die Umgebungsvariablen DB_HOST, DB_PORT, DB_NAME, DB_USER und DB_PASSWORD verwendet.
Verbindung testenSchaltfläche–Prüft die Verbindung über den Admin-Endpunkt /postgresql-csv-api/test-connection und zeigt Datenbankname und Serverversion. Die Verbindung muss dafür bereits deployt sein.

Modellregister, Registerkarte Modelle​

Links listet der Dialog alle Modelle mit Suchfeld und Schaltfläche Modell hinzufügen; rechts bearbeiten Sie das ausgewählte Modell. Die Modelle werden als JSON in der Node-Eigenschaft models gespeichert.

FeldTypStandardBedeutung
Öffentlicher ModellnameTextleerBildet den Pfad des Endpunkts, zum Beispiel weather-observed. Erlaubt sind Kleinbuchstaben, Ziffern und Bindestriche (^[a-z0-9]+(?:-[a-z0-9]+)*$); Namen müssen eindeutig sein.
Status: AktivKontrollkästchenaktivNur aktive Modelle werden ausgeliefert; inaktive beantwortet der Endpunkt mit 400.
SchemaTextleerPostgreSQL-Schema der Tabelle.
TabelleTextleerTabellenname.
ZeitspalteTextleerSpalte mit dem Zeitstempel, nach der gefiltert und sortiert wird.
FrequenzAuswahlMonatlichmonth: Export je Kalendermonat, Parameter month. year: Export je Kalenderjahr, Parameter year.
Point-Spalte (optional)TextleerPostGIS-Geometriespalte; der Export ergänzt daraus die Spalten longitude und latitude (ST_X/ST_Y), fehlende Geometrien ergeben 0.0.
Spalten ausschließenUnteransichtleerSpalten laden liest die Spalten der Tabelle über /postgresql-csv-api/columns; angehakte Spalten fehlen in der CSV. Umbenannte Spalten lassen sich nicht ausschließen.
Entitäten ausschließenUnteransichtleerEntity-IDs laden liest über /postgresql-csv-api/entities die eindeutigen, nicht leeren Werte der Spalte entity_id aus dem vorherigen vollständigen Monat beziehungsweise Jahr; angehakte IDs werden nicht exportiert. IDs können nicht manuell eingegeben werden; gespeicherte IDs, die im geladenen Zeitraum fehlen, bleiben sichtbar.
Spalten umbenennenUnteransichtleerZuordnungen Quellspalte → öffentlicher Header. Quellspalten müssen gültige Bezeichner sein, Header dürfen beliebigen Text enthalten, aber nicht leer oder doppelt sein. longitude und latitude sind reserviert.

Schema, Tabelle, Zeitspalte, Point-Spalte und ausgeschlossene Spalten müssen dem Muster ^[a-z_][a-z0-9_]*$ entsprechen. Der Dialog lehnt das Speichern ungültiger Modelle ab („Bitte eindeutige Modellnamen und gültige PostgreSQL-Bezeichner verwenden“); die Laufzeit prüft dieselben Regeln erneut beim Deploy.

PostgreSQL CSV API (postgresql-csv-api)​

FeldTypStandardBedeutung
NameTextleerAnzeigename des Nodes im Flow.
RegisterKonfigurationsnode–Modellregister mit Modellen und Verbindung (Pflichtfeld).

Der Dialog zeigt zur Information die registrierte Route GET /api/opendata/v1/:model.csv.

Datenbankrechte

Der Datenbankbenutzer benötigt USAGE auf jedem konfigurierten Schema und SELECT auf jeder veröffentlichten Tabelle sowie Lesezugriff auf information_schema.columns. Schreibrechte sind nicht erforderlich. Verwenden Sie einen eigenen, nur lesenden Datenbankbenutzer.

Eingang​

Der Node hat keinen Eingang im Flow. Er wird durch HTTP-Anfragen an die registrierte Route ausgelöst:

ElementTypBedeutung
GET /api/opendata/v1/<Modellname>.csvRoute<Modellname> ist der öffentliche Modellname eines aktiven Modells im Register.
?month=YYYY-MMQuery-ParameterNur bei Frequenz Monatlich: gewünschter Kalendermonat. Ohne Parameter wird der vorherige vollständige Monat exportiert.
?year=YYYYQuery-ParameterNur bei Frequenz Jährlich: gewünschtes Kalenderjahr. Ohne Parameter das vorherige vollständige Jahr.
Authentifizierung–Der Node selbst prüft keine Zugangsdaten und keine API-Schlüssel. Die Route liegt auf httpNode und unterliegt damit nur den in settings.js konfigurierten Einstellungen httpNodeAuth beziehungsweise httpNodeMiddleware. Für den öffentlichen Zugang ist ein API-Gateway vorgesehen (siehe Hinweise).

Zeitraumgrenzen werden in der Zeitzone Europe/Berlin berechnet. Zukünftige Monate oder Jahre werden mit 400 abgelehnt.

Ausgang​

Der Node sendet keine Nachricht in den Flow. Die HTTP-Antwort ist eine CSV-Datei mit Content-Type: text/csv; charset=utf-8, Content-Disposition: attachment; filename="<Modellname>-<Zeitraum>.csv" und Cache-Control: no-store.

"entity_id","time_index","temperature","relative_humidity","longitude","latitude"
"urn:ngsi-ld:WeatherObserved:station-01","2026-09-01T00:10:00.000Z","14.2","81","8.353","50"
"urn:ngsi-ld:WeatherObserved:station-01","2026-09-01T00:20:00.000Z","14.1","82","8.353","50"
ElementBedeutung
KopfzeileAlle Spalten der Tabelle (SELECT t.*) in Tabellenreihenfolge ohne ausgeschlossene Spalten, bei Point-Spalte ergänzt um longitude und latitude; Header gemäß Umbenennungen.
ZeilenAufsteigend nach der Zeitspalte sortiert. Jeder Wert steht in doppelten Anführungszeichen, enthaltene Anführungszeichen werden verdoppelt. NULL wird leer ausgegeben, Datumswerte als ISO 8601, Objekte und Arrays als JSON. Zeilentrenner ist CRLF.
Leerer ZeitraumLiefert eine CSV, die nur die Kopfzeile enthält; die Spalten stammen dann aus information_schema.columns.
HTTP 200Erfolgreicher Export.
HTTP 400Unbekanntes oder inaktives Modell (Unsupported OpenData model.), ungültiger Zeitparameter (Invalid month. Use YYYY-MM., Invalid year. Use YYYY.) oder zukünftiger Zeitraum (Future months are not available., Future years are not available.) als JSON {"error": "…"}.
HTTP 500Datenbank- oder Konfigurationsfehler, zum Beispiel fehlende umbenannte Quellspalte oder doppelte Header. Die Antwort lautet immer The OpenData export is currently unavailable.; Details stehen nur im Node-RED-Protokoll.

Beispiel-Flow​

Das Paket bringt einen Beispiel-Flow mit. Sie importieren ihn in Node-RED über Menü → Importieren → Beispiele → @htag/node-red-contrib-hypertegrity-endpoints → postgresql-csv-api. Alternativ laden Sie die Datei postgresql-csv-api.json herunter und importieren sie über Menü → Importieren. Nach dem Import legen Sie im Bearbeitungsdialog die Verbindung, das Register und mindestens ein Modell an.

Schritt 1

Verbindung anlegen

Im Register wählen Sie unter PostgreSQL „Neu hinzufügen“ und tragen Host, Datenbank und Zugangsdaten ein oder nutzen die DB_*-Umgebungsvariablen.

Schritt 2

Modell definieren

Auf der Registerkarte Modelle legen Sie Modellname, Schema, Tabelle, Zeitspalte und Frequenz fest und schließen Spalten oder Entitäten aus.

Schritt 3

Deploy und Abruf

Nach dem Deploy liefert GET /api/opendata/v1/<Modellname>.csv die Datei, zum Beispiel per Browser oder curl.

Beispiel-Flow als JSON anzeigen
[
{"id": "tab1", "type": "tab", "label": "Endpoints", "disabled": false, "info": ""},
{"id": "api1", "type": "postgresql-csv-api", "z": "tab1", "name": "", "x": 200, "y": 100, "wires": []},
{"id": "c1", "type": "comment", "z": "tab1", "name": "PostgreSQL CSV API: Creates an API Endpoint for PostgreSQL in Nodered", "info": "", "x": 320, "y": 40, "wires": []}
]

Status und Fehler​

AnzeigeBedeutung
Grüner Punkt „GET /api/opendata/v1/:model.csv“ (API-Node)Route registriert, Verbindungspool bereit.
Roter Ring „missing registry or httpNode“ (API-Node)Kein Register ausgewählt oder Node-RED stellt keinen httpNode-Server bereit.
Roter Ring „duplicate route“ (API-Node)Ein zweiter PostgreSQL-CSV-API-Node ist bereits aktiv.
Roter Ring „database unavailable“ (API-Node)Die ausgewählte Verbindung ist noch nicht deployt (Could not create PostgreSQL pool: …).
Grüner Punkt „2 model(s)“ (Register)Modelle erfolgreich geladen und validiert.
Roter Ring „invalid configuration“ (Register)Ein Modell verletzt die Bezeichnerregeln oder ein Modellname ist doppelt; Details im Protokoll (Invalid schema for …, Duplicate public model name: …).
Fehler „PostgreSQL pool error: …“ (Verbindung)Fehler im Verbindungspool, zum Beispiel Verbindungsabbruch.
Fehler im Protokoll bei HTTP 500Die Ursache (Datenbankfehler, Configured renamed column does not exist: …, Configured output column names are not unique) wird nur protokolliert, nicht an den Client gesendet.

Hinweise​

  • Schutz vor SQL-Injection: Schema, Tabelle, Zeitspalte, Point-Spalte und Spaltennamen werden vor der Verwendung gegen das Muster ^[a-z_][a-z0-9_]*$ geprüft (Allowlist) und nur dann in die Abfrage eingesetzt. Der Modellname aus der URL wird nie in SQL verwendet, sondern nur im Register nachgeschlagen. Zeitgrenzen und ausgeschlossene Entity-IDs gehen als Abfrageparameter ($1, $2, …) an PostgreSQL. Freie Filterparameter gibt es nicht.
  • Zugriffsschutz: Der Node authentifiziert Anfragen nicht. Node-RED darf nicht direkt aus dem öffentlichen Netz erreichbar sein. Vorgesehen ist ein API-Gateway (APISIX), das den öffentlichen Präfix /opendata/v1/* auf /api/opendata/v1/* umschreibt, einen API-Schlüssel (key-auth, Header X-API-Key) prüft und nur diese Route veröffentlicht. Der Node-RED-Editor darf nicht über das Gateway erreichbar sein.
  • Admin-Endpunkte: Spalten laden, Entity-IDs laden und Verbindung testen laufen über httpAdmin und verlangen die Berechtigung flows.read des Node-RED-Editors. Fehlermeldungen daraus nennen keine Datenbankdetails.
  • Voraussetzungen an die Tabelle: Für das Ausschließen von Entitäten und für Entity-IDs laden muss die Tabelle eine Spalte entity_id besitzen. Für die Point-Spalte wird die Erweiterung PostGIS benötigt (ST_X, ST_Y). Ausgeschlossene Spalten werden aus der Datenbank gelesen, aber nicht ausgegeben.
  • Zeiträume: Monats- und Jahresgrenzen werden mit make_timestamptz(…, 'Europe/Berlin') gebildet; Zeitstempel in der CSV erscheinen in UTC (ISO 8601).
  • Last: Jede Anfrage löst eine vollständige Abfrage des Zeitraums aus; es gibt keinen Cache (Cache-Control: no-store). Für große Tabellen empfiehlt sich ein Index auf der Zeitspalte und gegebenenfalls Caching im Gateway.
  • Datenschutz: Exportierte Tabellen können personenbezogene Daten enthalten, etwa Geräte, die einzelnen Haushalten zugeordnet sind, oder Standorte einzelner Personen. Der Node entfernt nichts automatisch. Prüfen Sie jedes Modell vor der Veröffentlichung, schließen Sie betroffene Spalten und entity_id-Werte aus und dokumentieren Sie die Freigabe als Open Data.
  • Einheiten: Werte werden unverändert aus der Datenbank übernommen; benennen Sie Spalten mit Einheiten um, zum Beispiel Temperatur (°C).

Weiterführende Themen​

Referenzen​