Analysieren von YAML zum Erstellen dynamischer Abfragen in der Shell

Analysieren von YAML zum Erstellen dynamischer Abfragen in der Shell

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 dieyqParser 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 SELECTAnweisungen, 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 yqder 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 yqkö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 configArray und erstellt einen psqlBefehl für jedes Element. Der psqlBefehl erhält seine Argumente -pund -dOptionen aus den Werten portund Einträgen database_name(für die Shell mit dem @shAusgabeoperator 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 valuesWert unverändert für die zu extrahierenden Felder und den nameWert 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 -soder mit auswerten eval.

verwandte Informationen