YAML を解析してシェルで動的クエリを作成する

YAML を解析してシェルで動的クエリを作成する

私はスクリプト作成の初心者で、提供されたYAMLドキュメントに基づいてSQLクエリを作成するシェルスクリプトを作成する方法を見つけるように求められました。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

使用アンドレイ・キスリュクのyqjqMike Farah の ではなく(JSON プロセッサの YAML 対応ラッパー) を使用すると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

これは配列を反復処理しconfigpsql各要素に対して 1 つのコマンドを作成します。コマンドはエントリのおよび値からpsqlその-pおよびオプション引数を取得します(出力演算子を使用してシェル用に引用符で囲まれます)。-dportdatabase_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

関連情報