Der YamlJdbc Treiber erlaubt es, YAML-Dateien über Jdbc zu lesen. Mit Hilfe von SQL-Abfragen können damit Daten aus einer YAML-Datei genauso wie aus einer Datenbanktabelle extrahiert und weiterverarbeitet werden.
Zur Abfrage werden Sequenzen (Listen) in einem YAML-Dokument als Tabellen angesprochen. Dazu verwendet man drei Komponenten in der Abfrage:
Das folgende YAML-Dokument kann man zum Beispiel mit Hilfe des Treibers einlesen:
people:
- id: 10
profession: scientist
fname: Henry
lname: Cavendish
- id: 21
profession: scientist
fname: Isaac
lname: Newton
- id: 33
profession: scientist
fname: Doctor
lname: Seltsam
Eine SQL-Abfrage über den YamlJdbc Treiber sieht dann so aus:
SELECT fname
, lname
, profession
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/people.yaml"."people"
COLUMNS(fname, lname, profession)
Dabei wird der Dateiname "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/people.yaml" als Schema angegeben und "people" ist ein Pfad-Ausdruck, der zu der "people" Sequenz im Dokument führt.
Innerhalb der "people" Sequenz werden mit "fname", "lname" und "profession" die Schlüssel der Mapping-Elemente angesprochen.
Das Ergebnis sieht dann so aus:
fname lname profession
------ --------- ----------
Henry Cavendish scientist
Isaac Newton scientist
Doctor Seltsam scientist
Wie gewohnt können Spaltenaliase vergeben werden, um die Spaltennamen umzubenennen:
SELECT fname AS vorname
, lname AS nachname
, profession AS beruf
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/people.yaml"."people"
COLUMNS(fname, lname, profession)
Das liefert dann:
vorname nachname beruf
------- --------- ---------
Henry Cavendish scientist
Isaac Newton scientist
Doctor Seltsam scientist
Neben den Datenspalten aus dem YAML-Dokument generiert der YamlJdbc Treiber zusätzliche Pseudospalten:
SELECT rownumber AS rownum
, "$id" AS zeilen_id
, fname
, lname
, profession
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/people.yaml"."people"
COLUMNS(fname, lname, profession)
Die Pseudospalte "rownumber" liefert eine fortlaufende Nummer für jeden Datensatz des Ergebnisses. Die Pseudospalte "$id" liefert eine fortlaufende Nummer für das Element im Dokument (beginnend bei 0). Das Ergebnis der Beispielabfrage sieht so aus:
rownum zeilen_id fname lname profession
------ --------- ------ --------- ----------
1 0 Henry Cavendish scientist
2 1 Isaac Newton scientist
3 2 Doctor Seltsam scientist
Hinweis: Es gibt weiterhin noch die Pseudospalte "$parentid". Sie liefert den Pfad des darüberliegenden Elements, dazu mehr im nächsten Abschnitt.
Ein Element in einem YAML-Dokument kann weitere verschachtelte Strukturen enthalten wie in dem folgenden Beispiel:
people:
- id: 10
profession: scientist
fname: Henry
lname: Cavendish
research:
- area: Chemistry
- area: Density of the Earth
- area: Electricity
- id: 21
profession: scientist
fname: Isaac
lname: Newton
research:
- area: Calculus
- area: Optics
- area: Gravity
Verschachtelte Strukturen können auf zwei Arten gelesen werden:
Bei einfachen verschachtelten Strukturen kann die Punkt-Notation verwendet werden:
company:
name: Acme Corp
employees:
- name: John Doe
department: IT
salary: 75000
- name: Jane Smith
department: HR
salary: 65000
SELECT name, department, salary
FROM "employees.yaml"."company.employees"
COLUMNS(name, department, salary)
Die Punkt-Notation "company.employees" navigiert durch die verschachtelte Struktur direkt zu der "employees" Sequenz.
Das liefert:
name department salary
---------- ---------- ------
John Doe IT 75000
Jane Smith HR 65000
Das ist das einfachste Verfahren, allerdings fehlt bei diesem Ansatz der Bezug zu den übergeordneten Elementen.
Der YamlJdbc Treiber unterstützt auch komma-separierte Navigation, ähnlich wie der JsonJdbc und XmlJdbc Treiber. Dies ist besonders nützlich bei verschachtelten Listen:
SELECT area
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/researcher.yaml"."people,research"
COLUMNS(area)
Hier navigiert "people" zum ersten Hierarchie-Level (Liste der Personen) und "research" (nach dem Komma) zum zweiten Level relativ zu jedem gefundenen "people" Element.
Das liefert alle "research" Einträge aller Personen:
area
--------------------
Chemistry
Density of the Earth
Electricity
Calculus
Optics
Gravity
Mit der Pseudospalte "$parentid" können Sie die Zugehörigkeit sehen:
SELECT "$parentid", area
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml/researcher.yaml"."people,research"
COLUMNS(area)
Das liefert:
$parentid area
--------- --------------------
0 Chemistry
0 Density of the Earth
0 Electricity
1 Calculus
1 Optics
1 Gravity
Die "$parentid" zeigt, zu welchem "people" Element die "research" Einträge gehören (0 = erstes Element, 1 = zweites Element, usw.).
Die Pseudospalte "$parentid" ermöglicht die Korrelation zwischen verschachtelten Elementen und ihren Eltern-Elementen.
Best Practice für verschachtelte Hierarchien:
SELECT "$id", fname, lname
FROM "researcher.yaml"."people"
COLUMNS(fname, lname)
Das liefert:
$id fname lname
--- ------ ---------
0 Henry Cavendish
1 Isaac Newton
SELECT "$parentid", area
FROM "researcher.yaml"."people,research"
COLUMNS(area)
Das liefert:
$parentid area
--------- --------------------
0 Chemistry
0 Density of the Earth
0 Electricity
1 Calculus
1 Optics
1 Gravity
Punkt-Notation (company.employees
):
Komma-Separierung (people,research
):
Beispiel des Unterschieds:
data:
level1:
- item: A
level2:
- value: 1
- value: 2
-- Punkt-Notation: Direkt zu level2 (wenn Sie die Hierarchie nicht brauchen)
FROM "file.yaml"."data.level1.level2"
-- Komma-Separierung: Erhält Hierarchie-Information
FROM "file.yaml"."data.level1,level2"
Der YamlJdbc Treiber unterstützt Verzeichnisse als Systemtabellen. Das erlaubt in einer Loop-Query eines datasqill Moduls nach Dateien in einem Verzeichnis zu suchen, die dann anschließend geladen werden können.
Die folgende Abfrage benutzt die Funktion "files()" als Systemtabelle und ihre Spalten "directory" und "filename".
SELECT directory, filename
FROM "yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml".files()
WHERE filename LIKE '%.yaml'
ORDER BY filename
Als Ergebnis werden die gesuchten Dateien in dem verwendeten Verzeichnis zurückgeliefert:
directory filename
--------------------------------------------------- --------------
yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml books.yaml
yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml employees.yaml
yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml people.yaml
yamljdbc/src/test/resources/de/softquadrat/jdbc/yaml researcher.yaml
Der YamlJdbc Treiber liefert alle Ergebnisse als Text zurück. Eine Umwandlung in andere Datentypen muss in nachgelagerten Arbeitsschritten erfolgen.
YAML unterstützt verschiedene Datentypen (Strings, Numbers, Booleans, null), aber der Treiber konvertiert alle Werte in Strings für die JDBC-Ausgabe.
Sollte eine Abfrage keine Datensätze zurückgeben, so ist zu prüfen, ob der Pfad-Ausdruck in der FROM-Klausel tatsächlich zu einer YAML-Sequenz navigiert. Ist dies nicht der Fall, ignoriert der YamlJdbc Treiber die Abfrage und gibt keine Ergebnisse zurück.
Der YamlJdbc Treiber liefert für selektierte Spalten in der SELECT-Klausel deren Inhalt zurück. Ist der angesprochene Schlüssel nicht vorhanden, wird ein Null-Wert zurückgegeben.
items:
- id: 1
name: Test1
- id: 2
# name fehlt
SELECT id
, name
, description
FROM "test.yaml"."items"
COLUMNS(id, name, description)
id name description
-- ----- -----------
1 Test1 null
2 null null
Der YamlJdbc Treiber unterstützt aktuell keine YAML-Anker (&
) und -Aliase (*
). Diese werden vom YAML-Parser (SnakeYAML) aufgelöst, bevor die Daten verarbeitet werden.
Wenn ein Wert selbst eine komplexe Struktur (verschachteltes Mapping oder Sequenz) ist, wird er als String-Repräsentation zurückgegeben:
items:
- id: 1
name: Test
config:
setting1: value1
setting2: value2
SELECT id, name, config
FROM "test.yaml"."items"
COLUMNS(id, name, config)
Das "config" Feld wird als String-Repräsentation des verschachtelten Objekts zurückgegeben (z.B. {setting1=value1, setting2=value2}
).
Der YamlJdbc Treiber unterstützt verschiedene YAML-Formate:
Sequenz am Root-Level:
- id: 1
name: Item 1
- id: 2
name: Item 2
Verwendung: FROM "file.yaml"."/"
Benannte Sequenz:
items:
- id: 1
name: Item 1
- id: 2
name: Item 2
Verwendung: FROM "file.yaml"."items"
Einzelnes Mapping als Sequenz: Der Treiber behandelt auch ein einzelnes Mapping-Element als einzeilige Sequenz:
person:
id: 1
name: John
Verwendung: FROM "file.yaml"."person"
Dies gibt eine einzelne Zeile zurück.
Der YamlJdbc Treiber nutzt:
Für optimale Performance bei großen YAML-Dateien:
Da YAML-Dateien vollständig in den Speicher geladen werden:
Hinweis: YAML ist für kleinere Konfigurationsdateien optimiert. Für sehr große Datenmengen sind Formate wie JSON oder CSV effizienter.
Der YamlJdbc Treiber verwendet UTF-8 als Standard-Zeichensatz zum Lesen von YAML-Dateien. Dies ist der empfohlene Standard für YAML-Dokumente.
books:
- id: 1
category: fiction
title: The Great Gatsby
author: F. Scott Fitzgerald
year: 1925
price: 10.99
- id: 2
category: fiction
title: To Kill a Mockingbird
author: Harper Lee
year: 1960
price: 12.99
SELECT category, title, author, year, price
FROM "books.yaml"."books"
COLUMNS(category, title, author, year, price)
WHERE category = 'fiction'
company:
name: Acme Corp
departments:
- name: IT
employees:
- name: John Doe
salary: 75000
- name: Jane Smith
salary: 80000
- name: HR
employees:
- name: Bob Johnson
salary: 65000
-- Alle Mitarbeiter mit Department-Info
SELECT "$parentid" AS dept_id, name, salary
FROM "company.yaml"."company.departments,employees"
COLUMNS(name, salary)
servers:
- hostname: web01
ip: 192.168.1.10
role: webserver
active: true
- hostname: db01
ip: 192.168.1.20
role: database
active: true
- hostname: backup01
ip: 192.168.1.30
role: backup
active: false
SELECT hostname, ip, role
FROM "servers.yaml"."servers"
COLUMNS(hostname, ip, role, active)
WHERE active = 'true'
Der YamlJdbc Treiber bietet eine einfache und intuitive Möglichkeit, YAML-Dateien über SQL-Abfragen zu lesen:
Der Treiber eignet sich besonders für: