Я выполняю запрос в оболочке для доступа к таблице Google Bigquery. Не могу понять, что вызывает ошибку.

#!/bin/bash

file_path='/home/vikrant_singh_rana/test_bq_file.csv'

{
    read
    while IFS=, read -r name local_unit region_unit
    do
        test_tablename=XYZ_KLM_${name}
        echo $test_tablename
        bq query --format=pretty --use_legacy_sql=false --project_id='test-data-project' "select DATE(COLLECTTIME) DATE,count(distinct COLLECTTIME) as record_count FROM `${project_id}.Test_INGEST.${test_tablename}` where DATE(collecttime) >= '2020-12-01' group by DATE order by DATE asc;"
    done
} < $file_path

Ниже приведен входной файл для чтения:

vikrant_singh_rana@cloudshell:~$ cat test_bq_file.csv
name,local_unit,region_unit
AAAAA,hour,cell
BBBBB,15min,cell

Ошибка:

read_bq_table.sh: line 22: .Test_INGEST.XYZ_KLM_AAAAA: command not found
Error in query string: Error processing job 'test-data-project:bqjob_r54dd3bbd143fcd42_0000017667292a54_1': Syntax error: Unexpected keyword WHERE at [1:81]
0
Kusalananda 16 Дек 2020 в 00:19
2
Возможно, вам захочется прочитать bobby-tables.com — очистить данные, поступающие из этого CSV-файла. .
 – 
glenn jackman
15 Дек 2020 в 19:32

1 ответ

Лучший ответ

В строке с двойными кавычками

"select DATE(COLLECTTIME) DATE,count(distinct COLLECTTIME) as record_count FROM `${project_id}.Test_INGEST.${test_tablename}` where DATE(collecttime) >= '2020-12-01' group by DATE order by DATE asc;"

Секция

`${project_id}.Test_INGEST.${test_tablename}`

Будет рассматриваться оболочкой как подстановка команды. Это происходит потому, что обратные кавычки вводят подстановку команд, когда они встречаются без кавычек или, как здесь, внутри строк с двойными кавычками. Оболочка расширит переменные внутри обратных кавычек и попытается выполнить результат как команду, как если бы она сказала

$(${project_id}.Test_INGEST.${test_tablename})

Вывод, полученный при выполнении команды в пределах `...` или $(...), затем заменит подстановку команды, по крайней мере, если это было сделано намеренно с командой, которая имела смысл. В вашем случае обратные кавычки являются частью синтаксиса базы данных и должны передаваться как буквальные обратные кавычки, чтобы оболочка не пыталась делать с ними свое дело.

Если вы хотите, чтобы обратные кавычки были буквальными, рассмотрите возможность их цитирования:

"select DATE(COLLECTTIME) DATE,count(distinct COLLECTTIME) as record_count FROM \`$project_id.Test_INGEST.$test_tablename\` where DATE(collecttime) >= '2020-12-01' group by DATE order by DATE asc;"

Я также удалил ненужные фигурные скобки вокруг имен переменных.

В идеале вы также должны очищать значения переменных перед их внедрением в базу данных. Вы должны, как минимум, обнаруживать и отклонять строки, содержащие обратные кавычки.

Также обратите внимание, что код, который вы показываете, не устанавливает значение для переменной project_id (именно поэтому эта часть строки перед .Test_INGEST пуста в сообщении об ошибке).

2
Kusalananda 16 Дек 2020 в 00:36