2017-05-10 17 views
0

BigQuery 테이블에 대해 UDF를 호출하는 SQL 문을 실행하려고합니다. 이 문은 Python 스크립트 내에서 실행되며 호출은 BigQuery API를 통해 이루어집니다.UDF를 호출하는 Python 스크립트를 사용하여 BigQuery API를 사용하는 방법

UDF없이 간단한 SQL 문을 실행할 때 제대로 작동합니다. 그러나 UDF 스크립트 (로컬 또는 GCS 버킷에 저장 됨)를 사용하려고해도 동일한 오류가 계속 발생합니다. 이 내가 (나는 파이썬 실행기를 통해 스크립트를 실행) 내 로컬 터미널에 도착 :

Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/googleapiclient/http.py", line 840, in execute raise HttpError(resp, content, uri=self.uri) googleapiclient.errors.HttpError: https://www.googleapis.com/bigquery/v2/projects/[projectId]/queries?alt=json returned "Required parameter is missing">

을 그리고 이것은 내 파이썬 스크립트입니다

credentials = SignedJwtAssertionCredentials(
SERVICE_ACCOUNT_EMAIL, 
key, 
scope='https://www.googleapis.com/auth/bigquery') 

aservice = build('bigquery','v2',credentials=credentials) 
query_requestb = aservice.jobs() 

query_data = { 
    'configuration': { 
     'query': { 
      'userDefinedFunctionResources': [ 
       { 
        'resourceUri': 'gs://[bucketName]/[fileName].js' 
       } 
      ], 
      'query': sql 
     } 
    }, 
    'timeoutMs': 100000 
} 

query_response = query_requestb.query(projectId=PROJECT_NUMBER,body=query_data).execute(num_retries=0) 

어떤 생각 무엇을 '매개 변수가 누락'또는 방법 나는 이걸 달릴 수 있니?

답변

2

userDefinedFunctionResources을 지정하는 대신 'query' 본문에 CREATE TEMP FUNCTION을 사용하고 OPTIONS 절의 일부로 참조되는 라이브러리를 사용하십시오. 이 경우 standard SQL을 사용해야하며 user-defined functions의 설명서를 참조 할 수도 있습니다. 귀하의 질의는 다음과 같이 보일 것입니다 :

#standardSQL 
CREATE TEMP FUNCTION MyJsFunction(x FLOAT64) RETURNS FLOAT64 LANGUAGE js AS """ 
    return my_js_function(x); 
""" 
OPTIONS (library='gs://[bucketName]/[fileName].js'); 

SELECT MyJsFunction(x) 
FROM MyTable; 
+0

빠른 응답 Elliott에 감사드립니다. '표준 SQL '을 사용하고 두 개의 분리 된 UDF 파일로 함수를 호출하는 것은'OPTIONS' 절을 통해 가능합니다. JS 함수의 IF 문에서 'if'를 소문자 *로 사용해야한다는 점에 유의하십시오 ('레거시 SQL'이있는 UDF를 사용하는 경우와 반대). 이 솔루션은 작동합니다. 그러나 우리가 '레거시 SQL'과 함께 사용할 수있는 방법을 이해하고 싶어합니다. – kekchoze

0

내가 실행하고 싶었 쿼리가 나는 보통의 UDF를 사용 채널 마케팅으로 트래픽과 매출을 분류하는 것이었다. 이것은 standard SQL을 사용하여 실행 한 쿼리입니다.

CREATE TEMPORARY FUNCTION 
    mktchannels(source STRING, 
    medium STRING, 
    campaign STRING) 
    RETURNS STRING 
    LANGUAGE js AS """ 
return channelGrouping(source,medium,campaign) // where channelGrouping is the function in my channelgrouping.js file which contains the attribution rules 
    """ OPTIONS (library=["gs://[bucket]/[path]/regex.js", 
    "gs://[bucket]/[path]/channelgrouping.js"]); 
WITH 
    traffic AS (// select fields from the BigQuery table 
    SELECT 
    device.deviceCategory AS device, 
    trafficSource.source AS source, 
    trafficSource.medium AS medium, 
    trafficSource.campaign AS campaign, 
    SUM(totals.visits) AS sessions, 
    SUM(totals.transactionRevenue)/1e6 as revenue, 
    SUM(totals.transactions) as transactions 
    FROM 
    `[datasetId].[table]` 
    GROUP BY 
    device, 
    source, 
    medium, 
    campaign) 
SELECT 
    mktchannels(source, 
    medium, 
    campaign) AS channel, // call the temp function set above 
    device, 
    SUM(sessions) AS sessions, 
    SUM(transactions) as transactions, 
    ROUND(SUM(revenue),2) as revenue 
FROM 
    traffic 
GROUP BY 
    device, 
    channel 
ORDER BY 
    channel, 
    device; 

을 그리고 파이썬 스크립트 :이 쿼리는 변수 sql에서 내가 읽은 파일 및 저장소에 저장됩니다

fd = file('myquery.sql', 'r') 
sql = fd.read() 
fd.close() 

query_data = { 
    'query': sql, 
    'maximumBillingTier': 10, 
    'useLegacySql': False, 
    'timeoutMs': 300000 
} 

희망이 미래에 누군가를 도와줍니다!