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

이는 배열을 반복하여 각 요소에 대해 config하나의 명령을 생성합니다 . psql명령 은 항목 및 값(출력 연산자를 사용하여 쉘에 대해 인용됨 ) 에서 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.

관련 정보