2017-02-16 2 views
1

Мне удалось получить запрос, работающий с веб-интерфейсом и UDF. Когда я поместил его в свой встроенный код, я получил ответ «400», «отсутствующий требуемый параметр». У меня есть код javascript в bucket облако хранилища Google, и я тестировал его с помощью параметра веб-интерфейса, чтобы использовать внешний код, а не код в редакторе UDF. Вы должны очистить это текстовое поле и выберите ссылку с этой линией в области параметров:BIgQuery UDF Javascript работает в веб-интерфейсе, но не внедрен

UDF Source URIs Edit Inline UDF 

Так значит BQ Web UI находит свой UDF, и она работает так же, как с тем же кодом в редакторе UDF , Я предполагаю, что запрос не отформатирован должным образом.

Я следую документации для изменения запроса ... Документация [здесь] [1] и явно просто фрагмент полного API запросов.

"configuration": { 
    "query": { 
     "userDefinedFunctionResources": [ 
     { 
      "inlineCode": "var someCode = 'here';" 
     }, 
     { 
      "resourceUri": "gs://some-bucket/js/lib.js" 
     } 
     ], 
     "query": "select a from myFunc(T);" 
    } 
    } 

Я интерпретировал это так:

var request = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     'configuration': { 
      'query' : { 
       'userDefinedFunctionResources': [ 
       { 
        'inlineCode' : '' 
       }, 
       { 
        'resourceUri': 'gs://cloudfiledatetype/UDF/udfLatestProcTimeAllRegions.js' 
       } 
       ], 
       'query': queryAll 
      } 
     } 
    }); 

Кстати, я попытался удалить опцию inLineCode и получил ту же ошибку. Там нет никакой документации о том, как форматировать ПОЛНЫЙ запрос ...

В качестве теста, я удалил ссылку на UDF и удалил параметр конфигурации, так что просьба является хлеб и масло:

var request = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     'query': queryAll 
    }); 

И это отлично работает: нет ошибки 400.

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

Я также читал, что существует обеспокоенность по поводу того, что UDF живет на лишении. Я использую UDF, потому что я не могу запросить нужный запрос без него. Я мог бы, вероятно, сделать это с помощью LAG, но запрос всегда отклоняется в опции формата в определении OVER ... Arggg ..

Полностью работающий REAL-LIFE примеры расширенных функций действительно оценят Google.

Для лучшей документации: вот мой UDF:

var lastInputA = -1; 
    function passthroughExample(row, emit) { 

    // handle 
    if (row.inputA != lastInputA) { 
     emit({outputC: row.inputC}); 
    } 
    lastInputA = row.inputA; 
    } 


    bigquery.defineFunction(
    'passthrough',       // Name of the function exported to SQL 
    ['inputA', 'inputB', 'inputC'],   // Names of input columns 
    [{'name': 'outputC', 'type': 'integer'}], 
    passthroughExample      // Reference to JavaScript UDF 
); 

Это делает что-то очень простое, но я видел пару постов на SO о том, как справиться с подобной проблемой. У меня есть несколько entier с тем же самым окном процесса, для каждого дня startTime и endTime, но обрабатываются в разные дни с другим временем процесса. Я хочу выбрать более поздний, поскольку у него есть последний код. Обратите внимание, что код выводит только последние времена процесса. Таким образом, в запросе я могу это сделать

WHERE 
     processTime IN ((
     SELECT 
     outputC 
     FROM 
     passthrough (
     SELECT 
      summaryStartTimeStamp AS inputA, 
      summaryEndTimeStamp AS inputB, 
      processTime AS inputC 

Если сделать запрос, чтобы получить все дни, и порядок со временем старта по возрастанию и убыванию времени процесса, вы получите строки с последнего времени процесса, а затем строк с повторением startTime и endTime и более ранним временем процесса. Таким образом, UDF находит, когда startTime меняет и испускает эту строку. Он отклоняет строки до тех пор, пока startTime не изменится.

Вот пример данных перед UDF. Это вход в UDF.

summaryStartTimeStamp summaryEndTimeStamp processTime 
1468206000000 1468292400000 1478668368824 
1468206000000 1468292400000 1474504378494 
1468206000000 1468292400000 1472261683703 
1468206000000 1468292400000 1471908635453 
1468292400000 1468378800000 1478668668857 
1468292400000 1468378800000 1474504654098 
1468292400000 1468378800000 1472261923772 
1468292400000 1468378800000 1471908956622 
1468378800000 1468465200000 1478669028973 
1468378800000 1468465200000 1474504910553 
1468378800000 1468465200000 1472262223831 
1468378800000 1468465200000 1471916440493 
1468465200000 1468551600000 1478669269089 
1468465200000 1468551600000 1474505174929 
1468465200000 1468551600000 1472262463965 
1468465200000 1468551600000 1471917212326 

Вот выход из ОДС с redudant линии удалены, и последний раз процесс в outputC

outputA   outputB   outputC 
1468206000000 1468292400000 1478668368824 
1468292400000 1468378800000 1478668668857 
1468378800000 1468465200000 1478669028973 
1468465200000 1468551600000 1478669269089 

Вот запрос с использованием UDF в WebUI ...

SELECT 
    outputA, outputB, outputC 
FROM 
    passthrough (
    SELECT summaryStartTimeStamp as inputA, summaryEndTimeStamp as inputB, processTime as inputC 
    FROM 
    [xxx removed ] 
    WHERE 
    eventType == "MAPFIT" 
    GROUP BY 
    inputA, inputB, inputC 
    ORDER BY 
    inputA,inputC DESC 
    LIMIT 
    1000) 
ORDER by outputA 
LIMIT 1000 

с этим UDF в окне редактора UDF

var lastInputA = -1; 
function passthroughExample(row, emit) { 

    // handle 
    if (row.inputA != lastInputA) { 
     emit({outputC: row.inputC}); 
    } 
    lastInputA = row.inputA; 
} 


bigquery.defineFunction(
    'passthrough',       
    ['inputA', 'inputB', 'inputC'],   
    [{'name': 'outputC', 'type': 'integer'}], 
    passthroughExample      
); 

В этом примере я выводил начальное и конечное время для удобства чтения. В встроенном коде я использовал модифицированную версию, которая выводит только время процесса, поэтому выберите процесс Times, который находится в подзапросе.

Я мог бы сделать это без UDF, имея тот же запрос, а затем обнаружение с помощью startTime не будет равным затуханию startTime на единицу.

Мой вопрос: почему отсутствует необходимый параметр для запроса яваскрипта отформатирован в верхней части этого вопроса .. Спасибо

UPDATE: Я пытался все возможные комбинации определения запроса и у меня есть разные ошибка теперь .. Я избавился от ошибки «400: требуемый параметр отсутствует». Теперь я получаю «400, Неизвестный TVF: пересылка». «Passthrough» - это имя UDF.

Таким образом, запрос JSON-анализатор насыщен конфигурацией, но он все еще не может найти UDF. Вот новое определение запроса:

requests = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     "userDefinedFunctionResources": [ 
      { 
       "resourceUri": "gs://cloudfiledatetype/UDF/udfLatestProcTimeAllRegions.js" 
      }, 
     ], 
     'query': queryAll 

}); 

Обратите внимание, что если я выполняю запрос в WebUI и точки к этой UDF, он прекрасно работает. Я думаю, что проблема связана только со встроенными заданиями.

Я также попытался добавить ту же функцию в другую сторону: теперь я использовал этот запрос, где UDF добавлен как javascript blob в опции «inLineCode».

requests = gapi.client.bigquery.jobs.query({ 
     'projectId': project_id, 
     'timeoutMs': '60000', 
     "userDefinedFunctionResources": [ 
      { 
      "inlineCode": "var lastInputA = -1; function passthroughExample(row, emit) { if (row.inputA != lastInputA) { emit({outputC: row.inputC}); } lastInputA = row.inputA;} bigquery.defineFunction( 'passthrough', ['inputA', 'inputB', 'inputC'], [{'name': 'outputC', 'type': 'integer'}], passthroughExample);" 
      } 
     ], 
     'query': queryAll 

}); 

Снова я получаю ответ 400 с «Неизвестный TVF: сквозной проход». Так что я понятия не имею, почему это не удается ... Является ли это моим определением запроса или это то, что UDF не работает за пределами WebUI ??? Благодарю.

P.S. Если кто-то может добавить вкладки Big Query и UserDefinedFunctions на вкладках этого вопроса, это будет действительно оценено. В противном случае ребята в Google не может видеть это ....

+0

Любой с достаточно очков, пожалуйста, может изменить метку на этом включить большой запрос и UserdefinedFunctions так, что ребята в Google может видеть это. Я думаю, что это довольно простая проблема с функцией ... ее работы отлично работают в WebUI, но не в обычном вызове работы ... Спасибо – Paul

ответ

0

Я думаю, что проблема в том, что вы используете Jobs: query API, который не поддерживает UDF
Таким образом, вы должны использовать API Jobs: insert с configuration.query собственности, которая не поддерживает userDefinedFunctionResources

таким образом, чтобы подвести итог - вместо query метода попробовать startQuery метод

+0

, что является полезным ответом. Вы могли бы предоставить синтаксис, пожалуйста? – Paul

Смежные вопросы