Analizando YAML para crear consultas dinámicas en Shell

Analizando YAML para crear consultas dinámicas en Shell

Soy muy nuevo en el mundo de las secuencias de comandos y se me ha encomendado la tarea de encontrar una manera de crear una secuencia de comandos de shell que cree consultas SQL basadas en un documento YAML proporcionado. Podría rastrear elyqanalizador a utilizar; sin embargo, no sé cómo utilizar valores individuales de los nodos secundarios de YAML. El YAML de muestra que necesito analizar es:

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'

El guión que estoy intentando escribir actualmente no es más que SELECTdeclaraciones, pero evolucionará más adelante:

# 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

Si es posible, sin parecer necesitado, espero ver sugerencias sobre cómo puedo usar yqla biblioteca, dado que admite un montón de operaciones que tendré que realizar en este script una vez que se complete la parte SQL.

Pido disculpas si la pregunta es demasiado estúpida, sería la primera vez que hago scripts de shell.

Estoy usando la distribución Ubuntu 18.4 si eso es relevante.

Respuesta1

UsandoAndrey Kislyukyq(un contenedor compatible con YAML alrededor del procesador JSON jq) en lugar del de Mike Farah yq, puede crear las declaraciones de shell necesarias para ejecutar las consultas de esta manera:

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

o, si no te gusta usar 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

Esto itera sobre la configmatriz, creando un psqlcomando para cada elemento. El psqlcomando obtiene sus argumentos de opción -py de los valores y -dde la entrada (citados para el shell usando el operador de salida).portdatabase_name@sh

Las declaraciones SQL reales se proporcionan al comando a través de una redirección de documento aquí, delimitada por la cadena elegida arbitrariamente END_SQL. Las declaraciones utilizan el valuesvalor tal cual para los campos que deben extraerse y el namevalor como el nombre de la tabla de donde extraer los campos. No se realizan cotizaciones especiales sobre estos valores.

Dados los datos de la pregunta, el comando anterior genera el siguiente código de shell:

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

Luego puede ejecutar este código canalizándolo a sh -s, o evaluándolo con eval.

información relacionada