BigQuery:使用 REST API 加载表时“未找到”数据集

Posted

技术标签:

【中文标题】BigQuery:使用 REST API 加载表时“未找到”数据集【英文标题】:BigQuery: Dataset "Not Found" on table load with REST API 【发布时间】:2012-07-06 22:50:37 【问题描述】:

我正在尝试使用以此处的 python 示例代码为模型的 python 脚本将 CSV 文件加载到 BigQuery:https://developers.google.com/bigquery/docs/developers_guide

但是当我尝试使用 REST API 加载表时遇到以下错误:

'status': '200', 'content-length': '1492', 'expires': 'Fri, 01 Jan 1990 00:00:00 GMT', 'server': 'HTTP Upload Server Built on Jun 14 2012 02:12:09 (1339665129)', 'etag': '"tcivyOj9QvKAbuEJ5MEMf9we85w/-mxYhUDjvvydxcebR8fXI6l_5RQ"', 'pragma': 'no-cache', 'cache-control': 'no-cache, no-store, must-revalidate', 'date': 'Fri, 06 Jul 2012 22:30:55 GMT', 'content-type': 'application/json'


 "kind": "bigquery#job",
 "etag": "\"tcivyOj9QvKAbuEJ5MEMf9we85w/-mxYhUDjvvydxcebR8fXI6l_5RQ\"",
 "id": "firespotter.com:firespotter:job_d6b99265278b4c0da9c3033acf39d6b2",
 "selfLink": "https://www.googleapis.com/bigquery/v2/projects/firespotter.com:firespotter/jobs/job_d6b99265278b4c0da9c3033acf39d6b2",
 "jobReference": 
  "projectId": "firespotter.com:firespotter",
  "jobId": "job_d6b99265278b4c0da9c3033acf39d6b2"
 ,
 "configuration": 
  "load": 
   "schema": 
    "fields": [
     
      "name": "date",
      "type": "STRING"
     ,
     
      "name": "time",
      "type": "STRING"
     ,
     
      "name": "call_uuid",
      "type": "STRING"
     ,
     
      "name": "log_level",
      "type": "STRING"
     ,
     
      "name": "file_line",
      "type": "STRING"
     ,
     
      "name": "message",
      "type": "STRING"
     
    ]
   ,
   "destinationTable": 
    "projectId": "385479794093",
    "datasetId": "telephony_logs",
    "tableId": "table_name"
   ,
   "createDisposition": "CREATE_IF_NEEDED",
   "writeDisposition": "WRITE_TRUNCATE",
   "encoding": "UTF-8"
  
 ,
 "status": 
  "state": "DONE",
  "errorResult": 
   "reason": "notFound",
   "message": "Not Found: Dataset 385479794093:telephony_logs"
  ,
  "errors": [
   
    "reason": "notFound",
    "message": "Not Found: Dataset 385479794093:telephony_logs"
   
  ]
 

错误“385479794093”中列出的projectId不是我传入的projectId,是“项目号”。 projectId 应该是“firespotter.com:firespotter”:


 "kind": "bigquery#datasetList",
 "etag": "\"tcivyOj9QvKAbuEJ5MEMf9we85w/ZMa8z6LKMgWZIqLWh3ti2SsSs4g\"",
 "datasets": [
  
   "kind": "bigquery#dataset",
   "id": "firespotter.com:firespotter:telephony_logs",
   "datasetReference": 
    "datasetId": "telephony_logs",
    "projectId": "firespotter.com:firespotter"
   
  
 ]

当我在三个不同的地方传递正确的值时,为什么 REST API 坚持提供自己不正确的 projectId?还有其他地方需要我传入或设置Project ID吗?

供参考,这里是相关代码sn-p:

PROJECT = 'firespotter.com:firespotter'
DATASET = 'telephony_logs'


FLOW = OAuth2WebServerFlow(
    client_id='385479794093.apps.googleusercontent.com',
    client_secret='<a_secret_here>',
    scope='https://www.googleapis.com/auth/bigquery',
    user_agent='firespotter-upload-script/1.0')

def loadTable(http, projectId, datasetId, tableId, file_path, replace=False):
  url = "https://www.googleapis.com/upload/bigquery/v2/projects/" + projectId + "/jobs"
  # Create the body of the request, separated by a boundary of xxx
  mime_data = ('--xxx\n' +
            'Content-Type: application/json; charset=UTF-8\n' + '\n' +
            '\n' +
            '   "projectId": "' + projectId + '",\n' +
            '   "configuration": \n' +
            '     "load": \n' +
            '       "schema": \n' +
            '         "fields": [\n' +
            '          "name":"date", "type":"STRING",\n' +
            '          "name":"time", "type":"STRING",\n' +
            '          "name":"call_uuid", "type":"STRING",\n' +
            '          "name":"log_level", "type":"STRING",\n' +
            '          "name":"file_line", "type":"STRING",\n' +
            '          "name":"message", "type":"STRING"\n' +
            '        ]\n' +
            '      ,\n' +
            '      "destinationTable": \n' +
            '        "projectId": "' + projectId + '",\n' +
            '        "datasetId": "' + datasetId + '",\n' +
            '        "tableId": "' + tableId + '"\n' +
            '      ,\n' +
            '     "createDisposition": "CREATE_IF_NEEDED",\n' +
            '     "writeDisposition": "' + ('WRITE_TRUNCATE' if replace else 'WRITE_APPEND') + '",\n' +
            '     "encoding": "UTF-8"\n' +
            '    \n' +
            '  \n' +
            '\n' +
            '--xxx\n' +
            'Content-Type: application/octet-stream\n' +
            '\n')
  # Append data from the specified file to the request body
  f = open(file_path, 'r')
  header_line = f.readline()  # skip header line
  mime_data += f.read()

  # Signify the end of the body
  mime_data += ('--xxx--\n')

  headers = 'Content-Type': 'multipart/related; boundary=xxx'
  resp, content = http.request(url, method="POST", body=mime_data, headers=headers)
  print str(resp) + "\n"
  print content

# --- Main ----------------------------------------------
def main(argv):

  csv_path = args[0]

  # If the credentials don't exist or are invalid, run the native client
  # auth flow. The Storage object will ensure that if successful the good
  # credentials will get written back to a file.
  storage = Storage('bigquery2_credentials.dat') # Choose a file name to store the credentials.
  credentials = storage.get()
  if credentials is None or credentials.invalid:
    credentials = run(FLOW, storage)

  # Create an httplib2.Http object to handle our HTTP requests and authorize it
  # with our good credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

  loadTable(http, PROJECT, DATASET, 'table_name', csv_path, replace=True)

if __name__ == '__main__':
  main(sys.argv)

【问题讨论】:

【参考方案1】:

您最近是否将项目 ID 设置为 firespotter.com:firespotter?如果数据集是在项目命名之前创建的,那么旧项目 id 和新项目 id 之间将不匹配。有一个更新项目 ID 的自动化系统,但它可能尚未运行或出现问题(我现在正在度假,所以无法检查)。希望,如果你很快再试一次,它就会起作用。如果没有,请告诉我们。

【讨论】:

是的!我在同一天命名了这个项目(因为我认为它是必需的)。我在周五尝试了几个小时,但没有成功,但该脚本现在正在使用“firespotter.com:firespotter”projectId。谢谢乔丹!【参考方案2】:

这里有几个问题:

为什么我的加载作业失败了?只是为了检查一下,这是您发送的整个请求吗?如果是这样,看起来没有要加载的数据,即sourceUris 是空的。如果是这样,那就是问题所在,我们显然正在返回世界上最糟糕的错误消息。

为什么使用数字项目 ID? BigQuery 可互换使用项目名称和关联的数字 ID,因此您所看到的只是我们倾向于将项目名称转换为 ID确认一下,如果您访问 Google APIs Console 并查找您的项目,您是否在 url 中看到相同的数字 ID?

为什么要在多个地方指定项目 ID? 首先,您似乎将项目 ID 指定为作业中的***属性;那不应该是必要的。 (我怀疑它只是覆盖了您在作业参考本身中指定的任何项目 ID。)留下两个位置 - 一个作为作业参考的一部分,另一个作为表参考的一部分。这些实际上表示两种不同的东西 - 工作中的一个指定您要插入工作的项目,即谁为工作付费,而表中的一个指定结果表所在的项目,即谁拥有结果数据。通常,它们是相同的,但 API 允许它们是不同的。 (例如,如果您构建了一个需要将数据插入最终归客户所有的表中的服务,这可能会很有用。)

【讨论】:

我将一个 csv 文件附加到 MIME 数据中。我能够通过浏览器工具手动上传相同的 CSV 文件,在返回的结果中,数据集被列为“firespotter.com:firespotter:telephony_logs”。这似乎是两者之间的区别。 Alos,是的,当我访问 Google API 控制台时,我确实在 URL 中看到了 385479794093(项目编号)。如果我列出项目编号或字符串 ID 的数据集,我会看到 firespotter.com:firespotter:telephony_logs 的数据集。 我认为这是 BigQuery 中的一个错误。为了确认,我创建了另一个项目,但没有命名。然后我在同一个脚本中输入项目编号('725870756519')作为 projectId。它奏效了。

以上是关于BigQuery:使用 REST API 加载表时“未找到”数据集的主要内容,如果未能解决你的问题,请参考以下文章

加载作业尝试使用 java 将 json 插入 BigQuery 表时解析错误

从 DataFlow 加载到现有 BigQuery 表时是不是可以更新架构?

推断 BigQuery 表加载的 avro 架构

访问由电子表格支持的 bigquery 表时遇到 BadRequest/ForbiddenException

通过 POST 将 CSV 数据发送到 BigQuery REST API

使用 BigQuery REST 或 Java API 运行查询以获取 JSON 输出格式