Ich bin ein Neuling im Scripting und mir wurde die Aufgabe gestellt, einen Weg zu finden, ein Shell-Script zu skripten, das SQL-Abfragen auf Basis eines bereitgestellten YAML-Dokuments erstellt. Ich konnte dieyq
Parser zu verwenden; ich bin mir jedoch nicht sicher, wie ich einzelne Werte aus den YAML-Unterknoten verwenden soll. Beispiel-YAML, das ich parsen muss, ist:
config:
- system1:
database_name: database1
port: '1234'
table:
- name: table1
values: 'table_id, value1, 30, randomValue'
- name: table2
values: 'table_id, value1, randomValue, randomValue, value2'
- name: table2
values: 'table_id, value2, randomValue, randomValue'
- system2:
database_name: database2
port: '12345'
table:
- name: table4
values: 'table_id, value3, 30, randomValue'
- name: table5
values: 'table_id, randomValue, randomValue, value4'
- name: table6
values: 'table_id, value3, value4'
Das Skript, das ich derzeit zu schreiben versuche, besteht lediglich aus SELECT
Anweisungen, wird sich aber später weiterentwickeln:
# This will later be used to create insert/update queries based on the values so
# will be needing a handle for that too.
psql -h localhost -p $PORT -d $DATABASE << EOF
select * from $TABLE LIMIT 10;
EOF
Wenn möglich, würde ich mich, ohne bedürftig zu klingen, über Vorschläge zur Verwendung yq
der Bibliothek freuen, da sie eine Reihe von Operationen unterstützt, die ich mit diesem Skript durchführen muss, sobald der SQL-Teil abgeschlossen ist.
Ich entschuldige mich, wenn die Frage zu dumm ist, es wäre mein erstes Mal, dass ich Shell-Skripte schreibe.
Ich verwende die Ubuntu 18.4-Distribution, falls das relevant ist.
Antwort1
Verwenden vonAndrey Kislyuksyq
(ein YAML-fähiger Wrapper um den JSON-Prozessor jq
) anstelle von Mike Farahs yq
können Sie die zum Ausführen der Abfragen erforderlichen Shell-Anweisungen wie folgt erstellen:
yq -r '
.config[] |
map(
@sh "psql -h localhost -p \(.port) -d \(.database_name) <<END_SQL",
(.table | map("SELECT \(.values) FROM \(.name) LIMIT 10;"))[],
"END_SQL"
)[]' file
oder, wenn Sie nicht verwenden möchten map
:
yq -r '
.config[][] |
@sh "psql -h localhost -p \(.port) -d \(.database_name) <<END_SQL",
(.table[] | "SELECT \(.values) FROM \(.name) LIMIT 10;"),
"END_SQL"' file
Dies iteriert über das config
Array und erstellt einen psql
Befehl für jedes Element. Der psql
Befehl erhält seine Argumente -p
und -d
Optionen aus den Werten port
und Einträgen database_name
(für die Shell mit dem @sh
Ausgabeoperator in Anführungszeichen gesetzt).
Die eigentlichen SQL-Anweisungen werden dem Befehl über eine Here-Document-Umleitung übergeben, abgegrenzt durch die beliebig gewählte Zeichenfolge END_SQL
. Die Anweisungen verwenden den values
Wert unverändert für die zu extrahierenden Felder und den name
Wert als Namen der Tabelle, aus der die Felder extrahiert werden sollen. Für diese Werte werden keine besonderen Anführungszeichen verwendet.
Unter Berücksichtigung der Daten aus der Frage generiert der obige Befehl den folgenden Shell-Code:
psql -h localhost -p '1234' -d 'database1' <<END_SQL
SELECT table_id, value1, 30, randomValue FROM table1 LIMIT 10;
SELECT table_id, value1, randomValue, randomValue, value2 FROM table2 LIMIT 10;
SELECT table_id, value2, randomValue, randomValue FROM table2 LIMIT 10;
END_SQL
psql -h localhost -p '12345' -d 'database2' <<END_SQL
SELECT table_id, value3, 30, randomValue FROM table4 LIMIT 10;
SELECT table_id, randomValue, randomValue, value4 FROM table5 LIMIT 10;
SELECT table_id, value3, value4 FROM table6 LIMIT 10;
END_SQL
Sie können diesen Code dann ausführen, indem Sie ihn entweder an weiterleiten sh -s
oder mit auswerten eval
.