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.

관련 정보