#google-bigquery
#google-bigquery
Вопрос:
Мой вариант использования — создать временную таблицу и загрузить данные из запроса select, а затем извлечь таблицу в виде CSV в облачном хранилище с помощью Python API.
Я могу создать и загрузить временную таблицу с помощью задания запроса, однако не смог определить «таблицу назначения» из ответа на задание, который требуется для экспорта в облачное хранилище.
это код
from google.cloud import bigquery
bq_key = settings.BASE_DIR '/api_keys/storage_bq_admin.json'
bq_client = bigquery.Client.from_service_account_json(bq_key, project='my-project-id')
query = """
EXECUTE IMMEDIATE
"CREATE TEMP TABLE segusers1 (user_id STRING, client_id STRING, inserted_at TIMESTAMP) AS SELECT user_id,client_id,inserted_at FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY inserted_at DESC ) AS top FROM `project-id.prod.users_partition_by_client` WHERE partition_id = 3666 AND client_id = '123456' AND inserted_at > '2020-09-17 00:59:11.461')"
"""
query_job = bq_client.query(query, job_id="segment_temp_%s" % str(uuid.uuid4())) # Make an API request.
results = query_job.result() # Waits for job to complete.
bq_job_id = query_job.job_id
print(query_job.__dict__)
query_job возвращает
{'_retry': <google.api_core.retry.Retry object at 0x7fdc41758748>, '_result': <google.cloud.bigquery.job.QueryJob object at 0x7fdc3ca682e8>, '_exception': None, '_result_set': True, '_polling_thread': None, '_done_callbacks': [], '_properties': {'kind': 'bigquery#job', 'etag': '3uEKLSpG6pZPeLsnzA==', 'id': 'pid-107805:US.segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56', 'selfLink': 'https://bigquery.googleapis.com/bigquery/v2/projects/pid-107805/jobs/segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56?location=US', 'user_email': '', 'configuration': {'query': {'query': 'n EXECUTE IMMEDIATEn "CREATE TEMP TABLE segusers1 (user_id STRING, client_id STRING, inserted_at TIMESTAMP) AS SELECT user_id,client_id,inserted_at FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY inserted_at DESC ) AS top FROM `pid.prod.users_partition_by_client` WHERE partition_id = 3666 AND client_id = 'cl3666dnx3klmb' AND inserted_at > '2020-09-17 00:59:11.461')"n ', 'priority': 'INTERACTIVE', 'useLegacySql': False}, 'jobType': 'QUERY'}, 'jobReference': {'projectId': 'pid-107805', 'jobId': 'segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56', 'location': 'US'}, 'statistics': {'creationTime': 1600359344198.0, 'startTime': 1600359344308.0, 'endTime': 1600359346615.0, 'totalBytesProcessed': '1292600', 'query': {'totalBytesProcessed': '1292600', 'totalBytesBilled': '10485760', 'totalSlotMs': '6637', 'statementType': 'SCRIPT'}, 'totalSlotMs': '6637', 'numChildJobs': '1', 'scriptStatistics': {}}, 'status': {'state': 'DONE'}}, '_client': <google.cloud.bigquery.client.Client object at 0x7fdc42448588>, '_completion_lock': <unlocked _thread.lock object at 0x7fdc42355d00>, '_configuration': <google.cloud.bigquery.job.QueryJobConfig object at 0x7fdc423d8fd0>, '_query_results': <google.cloud.bigquery.query._QueryResults object at 0x7fdc42467da0>, '_done_timeout': None, '_transport_timeout': None}
из проводника API документа с использованием идентификатора задания
{
"kind": "bigquery#job",
"etag": "3uEKLSpg961G6pZPeA==",
"id": "pid-107805:US.segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56",
"selfLink": "https://content-bigquery.googleapis.com/bigquery/v2/projects/pid-107805/jobs/segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56?location=US",
"user_email": "storage-bq-admin@pid-107805.iam.gserviceaccount.com",
"configuration": {
"query": {
"query": "n EXECUTE IMMEDIATEn "CREATE TEMP TABLE segusers1 (user_id STRING, client_id STRING, inserted_at TIMESTAMP) AS SELECT user_id,client_id,inserted_at FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY inserted_at DESC ) AS top FROM `pid-107805.prod.users_partition_by_client` WHERE partition_id = 3666 AND client_id = 'cl3666dnx3klmb' AND inserted_at u003e '2020-09-17 00:59:11.461')"n ",
"priority": "INTERACTIVE",
"useLegacySql": false
},
"jobType": "QUERY"
},
"jobReference": {
"projectId": "pid-107805",
"jobId": "segment_temp_3f7e533f-eb64-427f-bbb6-d3e31d78ca56",
"location": "US"
},
"statistics": {
"creationTime": "1600359344198",
"startTime": "1600359344308",
"endTime": "1600359346615",
"totalBytesProcessed": "1292600",
"query": {
"totalBytesProcessed": "1292600",
"totalBytesBilled": "10485760",
"totalSlotMs": "6637",
"statementType": "SCRIPT"
},
"totalSlotMs": "6637",
"numChildJobs": "1",
"scriptStatistics": {}
},
"status": {
"state": "DONE"
}
}
оба возврата без требуемых сведений о таблице назначения, я полагаю, запрос должен содержать значения datasetId вновь созданной таблицы. Не уверен, чего мне здесь не хватает.
Ответ №1:
Это своего рода злоупотребление НЕМЕДЛЕННЫМ ВЫПОЛНЕНИЕМ и созданием ВРЕМЕННОЙ таблицы в вашем коде.
Если вы удалите оба, ваш запрос станет прямым выбором, например:
query = """
SELECT user_id,client_id,inserted_at ...
"""
Затем вы сможете найти таблицу назначения в задании, аналогичном:
{
"configuration": {
"jobType": "QUERY",
"query": {
"destinationTable": { <======== what you're looking for
"datasetId": "_c53c0a2640dc04748b94ebc5d7193a6976b85fa1",
"projectId": "yourProject",
"tableId": "anon8b75560af5d60d88fd40befe1371bb83696c86e1"
},
...
Комментарии:
1. Это создание обычной таблицы, не так ли? Я пытаюсь создать временную таблицу вместо обычной таблицы, для которой требуются сценарии. Сокращение затрат — основная причина, по которой я выбираю временную таблицу
2. Как эта таблица результатов запроса, так и временная таблица в сценариях находятся во временном наборе данных и имеют продолжительность жизни 24 часа, они ничем не отличаются.