Я совсем новичок в написании скриптов, и мне поручили придумать способ написать скрипт оболочки, который будет создавать SQL-запросы на основе предоставленного документа YAML. Я мог бы проследитьyq
парсер для использования; однако я застрял на том, как использовать отдельные значения из дочерних узлов YAML. Пример YAML, который мне нужно разобрать:
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'
Скрипт, который я сейчас пытаюсь написать, представляет собой не более чем SELECT
утверждения, но он будет развиваться позже:
# 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
Если это возможно, не выглядя при этом навязчивым, я бы хотел получить предложения о том, как я могу использовать yq
библиотеку, учитывая, что она поддерживает ряд операций, которые мне нужно будет выполнить с этим скриптом после завершения части SQL.
Прошу прощения, если вопрос слишком глупый, это мой первый опыт написания сценариев оболочки.
Я использую дистрибутив Ubuntu 18.4, если это актуально.
решение1
С использованиемАндрей Кислюкyq
(оболочка с поддержкой YAML вокруг процессора JSON jq
) вместо Майка Фараха yq
, вы можете создать операторы оболочки, необходимые для выполнения запросов, следующим образом:
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
или, если вам не нравится использовать 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
Это итерирует по config
массиву, создавая одну psql
команду для каждого элемента. psql
Команда получает свои -p
и -d
аргументы опции из записей port
и database_name
значений (заключенных в кавычки для оболочки с использованием @sh
оператора вывода).
Фактические операторы SQL передаются команде через перенаправление here-document, разделенное произвольно выбранной строкой END_SQL
. Операторы используют values
значение «как есть» для полей, которые необходимо извлечь, и name
значение в качестве имени таблицы, из которой следует извлечь поля. Для этих значений не выполняется никаких специальных кавычек.
Учитывая данные из вопроса, приведенная выше команда генерирует следующий код оболочки:
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
Затем вы можете выполнить этот код, либо передав его по конвейеру sh -s
, либо выполнив его с помощью eval
.