【发布时间】:2020-01-23 08:56:51
【问题描述】:
我需要从我的 Google Apps 脚本插件将数据流式传输到 BigQuery。
但我只需要使用我的服务帐号(我需要将数据插入我的 BigQuery 表,而不是用户的 BigQuery 表)
我按照这个例子:https://developers.google.com/apps-script/advanced/bigquery#load_csv_data
因为 Apps Script Advanced Service 本身不支持服务帐号,所以我需要稍微修改一下这个例子:
我需要从我的服务帐户获取 OAuth 令牌,而不是使用 Advanced Service BigQuery,然后使用 BigQuery Rest API 来处理相同的工作:
这就是我所做的:
function getBigQueryService() {
return (
OAuth2.createService('BigQuery')
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Caching
.setCache(CacheService.getUserCache())
// Locking
.setLock(LockService.getUserLock())
// Set the scopes.
.setScope('https://www.googleapis.com/auth/bigquery')
)
}
export const insertLog = (userId, type) => {
const bigQueryService = getBigQueryService()
if (!bigQueryService.hasAccess()) {
console.error(bigQueryService.getLastError())
return
}
const projectId = bigqueryCredentials.project_id
const datasetId = 'usage'
const tableId = 'logs'
const row = {
timestamp: new Date().toISOString(),
userId,
type,
}
const data = Utilities.newBlob(convertToNDJson(row), 'application/octet-stream')
// Create the data upload job.
const job = {
configuration: {
load: {
destinationTable: {
projectId,
datasetId,
tableId,
},
sourceFormat: 'NEWLINE_DELIMITED_JSON',
},
},
}
const url = `https://bigquery.googleapis.com/upload/bigquery/v2/projects/${projectId}/jobs`
const headers = {
Authorization: `Bearer ${bigQueryService.getAccessToken()}`,
'Content-Type': 'application/json',
}
const options = {
method: 'post',
headers,
payload: JSON.stringify(job),
}
try {
const response = UrlFetchApp.fetch(url, options)
const result = JSON.parse(response.getContentText())
console.log(JSON.stringify(result, null, 2))
} catch (err) {
console.error(err)
}
}
正如您在我的代码中看到的,我使用以下行获取 Blob 数据(这是我需要放入 BigQuery 表中的实际 json 数据):
const data = Utilities.newBlob(convertToNDJson(row), 'application/octet-stream')
但我不知道在哪里使用这个 data 和 BigQuery Rest API
文档没有提及:https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/insert
如何做到这一点?谢谢。
【问题讨论】:
-
您需要将文件和作业配置作为'multipart/related' 数据发送。请参阅相关的example。用于为您处理它的高级 Google 服务。现在,您需要自己完成此操作
-
作为@TheMaster 评论的附加信息,使用this GAS library 怎么样?该库使用 Google Apps 脚本创建并请求
multipart/form-data的类型。 -
@Tanaike:我看到 TheMaster 提到的是您的代码。有没有关于那些“\r\n”和“--”的文档。仅通过阅读代码很难理解该约定。另外,感谢您的图书馆,如果手动方式不起作用,我想我稍后会使用它。
-
@Tanaike:谢谢。我的意思是
the manual way就是您使用\r\n和--构建字符串的方式。但是我认为您提供的链接是我需要了解的developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
标签: google-apps-script google-bigquery google-apps-script-addon