#google-api #google-bigquery #bigquery-standard-sql #legacy-sql
#google-api #google-bigquery #устаревший sql
Вопрос:
Что
Кто-нибудь знает лучший способ идентификации / дифференциации представления или запроса, написанных на устаревшем или стандартном SQL, с использованием BigQuery API?
Единственным методом, который пришел на ум, было запустить SQL с dryRun
свойством, установленным на true
(это повлекло бы за собой минимальные затраты на обработку), и если это приведет к сбою с сообщением, включающим фразу «Попробуйте использовать стандартный SQL», я мог бы предположить, что это был устаревший SQL, в противном случае он работает и является стандартным. Например.
{
...
"code": 400,
"message":
"Invalid table name: `my-project.my_dataset.hello_world`
[Try using standard SQL (https://cloud.google.com/bigquery/docs/reference/standard-sql/enabling-standard-sql)]."
}
Почему
Я поддерживаю уровень интеграции (написанный в облачных функциях — Node.js 8) который переносит данные с помощью BigQuery API.
К сожалению, сообществу пользователей было разрешено писать представления и запросы либо на стандартном, либо на устаревшем SQL. Из-за многочисленных ограничений при работе с устаревшим SQL я хотел бы определить, какие запросы и представления написаны с его использованием, что позволяет мне соответствующим образом настроить метод обработки.
Ответ №1:
Кто-нибудь знает лучший способ идентификации / дифференциации представления или запроса, написанных на устаревшем или стандартном SQL, с использованием BigQuery API?
Вы можете попробовать использовать регулярное выражение javascript для определения типа SQL.
Вы можете использовать приведенный ниже фрагмент кода в качестве базового
isStandardSql(idString) {
let isStandard, fullId, partialId, projectId = '';
// This 'if' checks if the provided idString is of type standard and makes sure there is only one ':' in the expression (as in legacy syntax)
const splitted = idString.split(/[:.]/g);
if (splitted.length > 3) {
const __ret = this.try2findProjectId(idString, projectId);
idString = __ret.idString;
projectId = __ret.projectId;
}
if ((idString.match(/:/g))) {
// Regex that checks if the format of the id match legacy
let matched = idString.match(/([[]([^[]|[[][]])*[]])/g);
if (matched amp;amp; matched[0]) {
fullId = projectId matched[0].substring(1, idString.length - 1);
isStandard = false;
} else {
this.errorMessage("First Regex", idString);
}
// Same as the first only that here instead of ':' we are looking for '.' and we want to make sure there is more than 1 (as in standard syntax)
} else if ((idString.match(/./g) amp;amp; idString.match(/./g).length === 2)) {
// Regex that checks if the format of the id match standard
let matched = idString.match(/(`([^`]|``)*`)/g);// ? idString.match(/(`([^`]|``)*`)/g) : [idString];
if (matched amp;amp; matched[0]) {
fullId = projectId matched[0].substring(1, idString.length - 1);
isStandard = true
} else if(!matched amp;amp; idString){
fullId = projectId idString;
isStandard = true;
}
else {
this.errorMessage("Second Regex", idString);
}
}
else {//projectID.dataset
// In case of id without projectId of proxy "use" project.dataset
if(splitted.length === 2) {
fullId = '';
if (idString[0] === '[' amp;amp; idString[idString.length - 1] === ']') {
isStandard = false;
}
else if (idString[0] === '`' amp;amp; idString[idString.length - 1] === '`') {
isStandard = true;
}
partialId = idString.replace(/`|[|]/g, '')
}
else {
this.errorMessage("Third Regex", idString);
}
}
// Return values is flag the determine the type (standard or legacy) and id without staring/ ending chars (``, [])
return {
isStandard,
fullId: fullId,
partialId: partialId
};
}
try2findProjectId(idString, projectId)
{
let numOfInstances = 0
for (let i = idString.length; i > 0; i--) {
const char = idString[i - 1]
if (char === ':' || char === '.') {
numOfInstances
if (numOfInstances === 2) {
projectId = idString.substring(1, i - 1)
idString = idString.substring(i - 1, idString.length)
idString = idString[idString.length - 1] === '`' ? '`' idString : idString
idString = idString[idString.length - 1] === ']' ? '[' idString : idString
}
}
}
return {idString, projectId}
}
Комментарии:
1. Приятно! Знаете ли вы о каких-либо оговорках к регулярному выражению? Т.е. хитрые или странные примеры SQL, которые могут не подойти? Просто чтобы получить приблизительный процент риска? Или вы считаете это полным охватом?
2. У меня до сих пор отлично работает в течение нескольких месяцев без проблем. Если этот ответ поможет, пожалуйста, отметьте его как решение для других
3. Я пометил это как ответ, но мне пришлось немного изменить настройки, а также столкнуться с проблемой с первым оператором if «if (splitted. длина > 3)» потому что if ссылается на отсутствующую функцию «try2findProjectId».
4. @FreeZey спасибо, я добавил недостающую функцию, если в коде есть что еще улучшить, дайте мне знать