将 Bigquery 结果批量更新为 google 表(大约 50k 个结果)
Batch Update Bigquery results into google sheets(about 50k results)
我正在尝试使用脚本编辑器(Apps 脚本)将 BigQuery 结果流式传输到 google 工作表中。我正在关注这些 [文档][1] .
我遇到的问题是,数据未完全加载,挂起。我有很多行(超过 12 行)。我想我需要通过某种批量更新来优化“附加结果”部分。现在这是一个循环,我猜它不是很有效。
我想不明白。我尝试使用“.next()”但出现错误,函数不存在。我使用这些 [document][2].
如何优化附加结果部分?
这是整个代码(稍后我只包含了我要修改的部分):
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update','update')
.addToUi();
}
function update() {
run1("\"Filter1\"","\"FilterA\"","Sheet1);
run1("\"Filter2\"","\"FilterB\"","Sheet2");
};
function run1(filter1,filter2,output) {
var projectId = 'xxx';
var request = {
useLegacySql: false,
useQueryCache: false,
query: 'select * from table ' +
'where a1.col1 = ' + filter1 + ' and a1.col2 in ( ' + filter2 + ' ); '
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId,jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId,jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
if (rows) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name");
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log("Results spreadsheet created: %s",
spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}
};
具体这部分代码:
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
您需要在查询中使用更多过滤器或指定更少的列数。因为你可能犯的错误之一是
文件大小超过 10MB。因为在这种情况下行的限制是 50,000 行,所以在 12,000 或 15,000 行之间会出现错误。您可以将数据拆分为多个 google 工作表。
在这里您可以看到一些解决方案,您还可以在 this link 中看到更多文档。
您的查询结果可能太大。如果出现以下情况,您的查询将失败:
数据透视表有超过 50K 个结果。为了减少查询结果,您
可以:
- 使用过滤器限制结果
- 限制每个突破的行数
- 添加行、列、值和过滤器时关闭“显示总计”
- 结果大小超过 10MB。要减小大小,return 行或
列。
我相信你的目标如下。
- 您想减少脚本的处理成本。
这样的话,下面的修改怎么样?
修改后的脚本:
在您使用此脚本之前,please enable Sheets API at Advanced Google services。
发件人:
if (rows) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name");
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log("Results spreadsheet created: %s",
spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}
收件人:
if (rows) {
var headers = queryResults.schema.fields.map(function (field) {
return field.name;
});
var data = [headers, ...rows.map(({ f }) => f.map(({ v }) => v || ""))];
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
SpreadsheetApp.flush();
Sheets.Spreadsheets.Values.update({ values: data }, spreadsheet.getId(), output, { valueInputOption: "USER_ENTERED" });
// spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name"); // I'm not sure about this line.
Logger.log("Results spreadsheet created: %s", spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}
参考:
我正在尝试使用脚本编辑器(Apps 脚本)将 BigQuery 结果流式传输到 google 工作表中。我正在关注这些 [文档][1] .
我遇到的问题是,数据未完全加载,挂起。我有很多行(超过 12 行)。我想我需要通过某种批量更新来优化“附加结果”部分。现在这是一个循环,我猜它不是很有效。 我想不明白。我尝试使用“.next()”但出现错误,函数不存在。我使用这些 [document][2].
如何优化附加结果部分? 这是整个代码(稍后我只包含了我要修改的部分):
var ui = SpreadsheetApp.getUi();
ui.createMenu("Update")
.addItem('Update','update')
.addToUi();
}
function update() {
run1("\"Filter1\"","\"FilterA\"","Sheet1);
run1("\"Filter2\"","\"FilterB\"","Sheet2");
};
function run1(filter1,filter2,output) {
var projectId = 'xxx';
var request = {
useLegacySql: false,
useQueryCache: false,
query: 'select * from table ' +
'where a1.col1 = ' + filter1 + ' and a1.col2 in ( ' + filter2 + ' ); '
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId,jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId,jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
if (rows) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name");
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log("Results spreadsheet created: %s",
spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}
};
具体这部分代码:
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
您需要在查询中使用更多过滤器或指定更少的列数。因为你可能犯的错误之一是 文件大小超过 10MB。因为在这种情况下行的限制是 50,000 行,所以在 12,000 或 15,000 行之间会出现错误。您可以将数据拆分为多个 google 工作表。
在这里您可以看到一些解决方案,您还可以在 this link 中看到更多文档。
您的查询结果可能太大。如果出现以下情况,您的查询将失败:
数据透视表有超过 50K 个结果。为了减少查询结果,您 可以:
- 使用过滤器限制结果
- 限制每个突破的行数
- 添加行、列、值和过滤器时关闭“显示总计”
- 结果大小超过 10MB。要减小大小,return 行或 列。
我相信你的目标如下。
- 您想减少脚本的处理成本。
这样的话,下面的修改怎么样?
修改后的脚本:
在您使用此脚本之前,please enable Sheets API at Advanced Google services。
发件人:
if (rows) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name");
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log("Results spreadsheet created: %s",
spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}
收件人:
if (rows) {
var headers = queryResults.schema.fields.map(function (field) {
return field.name;
});
var data = [headers, ...rows.map(({ f }) => f.map(({ v }) => v || ""))];
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName(output);
sheet.clearContents();
SpreadsheetApp.flush();
Sheets.Spreadsheets.Values.update({ values: data }, spreadsheet.getId(), output, { valueInputOption: "USER_ENTERED" });
// spreadsheet.getSheetByName(output).getRange("C1").setValue("Modified_col_name"); // I'm not sure about this line.
Logger.log("Results spreadsheet created: %s", spreadsheet.getUrl());
} else {
Logger.log("No rows returned.");
}