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

使用アンドレイ・キースリュークyq(JSONプロセッサの周りのYAML対応ラッパーjq)Mike Farahの代わりに、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要素のコマンドを生成します。このコマンドは、psql項目の合計値(出力演算子を使用してシェルから引用)から-p合計オプション引数を取得します。-dportdatabase_name@sh

実際のSQL文はこのドキュメントリダイレクトを介してコマンドに提供され、ランダムに選択された文字列で区切られています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

おすすめ記事