Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.

Commit d522222

Browse files
authored
chore: add Jobs samples, add backoff to table update sample (#1524)
* chore: fix owlbot configs, regenerate * Apply suggestions from code review * WIP - two different ways * don't overwrite handwritten methods * change to sync file read * chore: periodic regen * run postprocessor * upgrade dependencies to node 18 * Revert "upgrade dependencies to node 18" This reverts commit b7ca3fc. * periodic regeneration + update to node 18 on autogen branch * fix lint errors * more lint fixes * listJobs sample * getJob request * createJob sample * cancel job sample * fix lint * fix license year * fix - add backoff to table update sample test * change to 5 seconds for backoff polling because of bq defaults * use async list jobs method, limit iterations * address alvaro comment * lint * fix indentation
1 parent 4098d55 commit d522222

File tree

7 files changed

+383
-1
lines changed

7 files changed

+383
-1
lines changed

samples/jobs/cancelJob.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
function main(projectId = 'my-project-id', jobId = 'existing-job-id') {
20+
// [START bigquery_cancel_job]
21+
// Import the Google Cloud client library
22+
const {BigQueryClient} = require('@google-cloud/bigquery');
23+
const bigqueryClient = new BigQueryClient();
24+
25+
async function cancelJob() {
26+
// Attempts to cancel a job.
27+
28+
/**
29+
* TODO(developer): Uncomment the following lines before running the sample.
30+
*/
31+
// const jobId = "existing-job-id";
32+
33+
const request = {
34+
projectId,
35+
jobId,
36+
};
37+
38+
// Attempt to cancel job
39+
const [response] = await bigqueryClient.cancelJob(request);
40+
41+
console.log(response.job.status);
42+
}
43+
// [END bigquery_cancel_job]
44+
cancelJob();
45+
}
46+
main(...process.argv.slice(2));

samples/jobs/createJob.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
function main(projectId = 'my-project') {
18+
// [START bigquery_create_job]
19+
// Import the Google Cloud client library and create a client
20+
const {BigQueryClient} = require('@google-cloud/bigquery');
21+
const {setInterval} = require('node:timers/promises');
22+
23+
const bigquery = new BigQueryClient();
24+
25+
async function createJob() {
26+
// Run a BigQuery query job.
27+
28+
const query = `SELECT country_name
29+
FROM
30+
bigquery-public-data.utility_us.country_code_iso
31+
LIMIT 10`;
32+
33+
const request = {
34+
projectId: projectId,
35+
job: {
36+
configuration: {
37+
query: {
38+
query: query,
39+
useLegacySql: {value: false},
40+
},
41+
labels: {'example-label': 'example-value'},
42+
},
43+
},
44+
};
45+
46+
// Make API request.
47+
const [job] = await bigquery.insertJob(request);
48+
const jobReference = job.jobReference;
49+
const jobId = jobReference.jobId;
50+
const getQueryResultsRequest = {
51+
projectId: projectId,
52+
jobId: jobId,
53+
location: jobReference.location.value,
54+
};
55+
// poll the job status every 3 seconds until complete
56+
// eslint-disable-next-line
57+
for await (const t of setInterval(3000)) { // no-unused-vars - this is the syntax for promise based setInterval
58+
const [resp] = await bigquery.jobClient.getQueryResults(
59+
getQueryResultsRequest,
60+
);
61+
if (resp.errors.length !== 0) {
62+
throw new Error('Something failed in job creation');
63+
}
64+
if (resp.jobComplete.value) {
65+
const rows = resp.rows;
66+
console.log('Rows:');
67+
rows.forEach(row => console.log(JSON.stringify(row)));
68+
break;
69+
}
70+
}
71+
}
72+
// [END bigquery_create_job]
73+
createJob();
74+
}
75+
main(...process.argv.slice(2));

samples/jobs/getJob.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
function main(projectId = 'my_project', jobId = 'existing-job-id') {
20+
// [START bigquery_get_job]
21+
// Import the Google Cloud client library
22+
const {BigQueryClient} = require('@google-cloud/bigquery');
23+
const bigquery = new BigQueryClient();
24+
25+
async function getJob() {
26+
// Get job properties.
27+
28+
/**
29+
* TODO(developer): Uncomment the following lines before running the sample.
30+
*/
31+
// const projectId = "my_project";
32+
// const jobId = "existing-job-id";
33+
34+
const request = {
35+
projectId,
36+
jobId,
37+
location: 'US',
38+
};
39+
const [job] = await bigquery.getJob(request);
40+
41+
console.log(`Job ${job.id} status: ${job.status.state}`);
42+
}
43+
// [END bigquery_get_job]
44+
getJob();
45+
}
46+
main(...process.argv.slice(2));

samples/jobs/listJobs.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
function main(projectId = 'my_project') {
20+
// [START bigquery_list_jobs]
21+
// Import the Google Cloud client library
22+
const {BigQueryClient} = require('@google-cloud/bigquery');
23+
const bigquery = new BigQueryClient();
24+
25+
async function listJobs() {
26+
// Lists all jobs in current GCP project.
27+
const request = {projectId: projectId};
28+
// limit results to 10
29+
const maxResults = 10;
30+
const iterable = bigquery.listJobsAsync(request);
31+
console.log('Jobs:');
32+
let i = 0;
33+
for await (const job of iterable) {
34+
if (i >= maxResults) {
35+
break;
36+
}
37+
console.log(job.id);
38+
i++;
39+
}
40+
}
41+
// [END bigquery_list_jobs]
42+
listJobs();
43+
}
44+
main(...process.argv.slice(2));

samples/models/listModelsStreaming.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// limitations under the License.
1414

1515
'use strict';
16-
//TODO(coleleah): update
1716

1817
// sample-metadata:
1918
// title: BigQuery List Models Streaming

samples/test/jobs.test.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
const {BigQueryClient} = require('@google-cloud/bigquery');
18+
const {assert} = require('chai');
19+
const {describe, it, before, after} = require('mocha');
20+
const {randomUUID} = require('crypto');
21+
const {setInterval} = require('node:timers/promises');
22+
23+
const cp = require('child_process');
24+
25+
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
26+
27+
const bigquery = new BigQueryClient();
28+
let jobId;
29+
const GCLOUD_TESTS_PREFIX = 'nodejs_samples_tests_jobs';
30+
31+
// the GCLOUD_PROJECT environment variable is set as part of test harness setup
32+
const projectId = process.env.GCLOUD_PROJECT;
33+
34+
describe('Jobs', () => {
35+
const datasetId = `${GCLOUD_TESTS_PREFIX}_${randomUUID()}`.replace(
36+
/-/gi,
37+
'_',
38+
);
39+
const query = `SELECT country_name
40+
FROM \`bigquery-public-data.utility_us.country_code_iso\`
41+
LIMIT 10`;
42+
const insertJobRequest = {
43+
projectId: projectId,
44+
job: {
45+
configuration: {
46+
query: {
47+
query: query,
48+
useLegacySql: {value: false},
49+
},
50+
},
51+
},
52+
};
53+
54+
before(async () => {
55+
if (projectId === undefined) {
56+
throw Error(
57+
'GCLOUD_PROJECT must be defined as an environment variable before tests can be run',
58+
);
59+
}
60+
const datasetObject = {
61+
datasetReference: {
62+
datasetId: datasetId,
63+
},
64+
location: 'US',
65+
};
66+
const datasetRequest = {
67+
projectId: projectId,
68+
dataset: datasetObject,
69+
};
70+
const [datasetResponse] = await bigquery.insertDataset(datasetRequest);
71+
assert.ok(datasetResponse);
72+
});
73+
after(async () => {
74+
const deleteRequest = {
75+
projectId: projectId,
76+
datasetId: datasetId,
77+
deleteContents: true,
78+
};
79+
await bigquery.deleteDataset(deleteRequest);
80+
const getDatasetRequest = {
81+
projectId: projectId,
82+
datasetId: datasetId,
83+
};
84+
try {
85+
await bigquery.getDataset(getDatasetRequest);
86+
} catch (err) {
87+
assert.strictEqual(
88+
err.details,
89+
`Not found: Dataset ${projectId}:${datasetId}`,
90+
);
91+
}
92+
});
93+
94+
describe('get + list jobs', () => {
95+
before('create a job to get/list', async () => {
96+
// Run query to create a job
97+
const [job] = await bigquery.insertJob(insertJobRequest);
98+
assert.ok(job);
99+
const jobReference = job.jobReference;
100+
const getQueryResultsRequest = {
101+
projectId: projectId,
102+
jobId: jobReference.jobId,
103+
location: jobReference.location.value,
104+
};
105+
jobId = getQueryResultsRequest.jobId;
106+
// poll the job status every 3 seconds until complete
107+
// eslint-disable-next-line
108+
for await (const t of setInterval(3000)) { // no-unused-vars - this is the syntax for promise based setInterval
109+
const [resp] = await bigquery.jobClient.getQueryResults(
110+
getQueryResultsRequest,
111+
);
112+
if (resp.errors.length !== 0) {
113+
throw new Error('Something failed in job creation');
114+
}
115+
if (resp.jobComplete.value) {
116+
break;
117+
}
118+
}
119+
});
120+
121+
it('should list jobs', async () => {
122+
const output = execSync(`node jobs/listJobs.js ${projectId}`);
123+
assert.match(output, /Jobs:/);
124+
assert.include(output, jobId);
125+
});
126+
127+
it('should retrieve a job', async () => {
128+
const output = execSync(`node jobs/getJob.js ${projectId} ${jobId}`);
129+
assert.include(output, `Job ${projectId}:US.${jobId}`);
130+
});
131+
});
132+
133+
describe('create + cancel jobs', () => {
134+
let jobId;
135+
before('create a job to cancel', async () => {
136+
// Run query to create a job
137+
const [job] = await bigquery.insertJob(insertJobRequest);
138+
assert.ok(job);
139+
jobId = job.jobReference.jobId;
140+
});
141+
it('should attempt to cancel a job', async () => {
142+
assert.exists(jobId);
143+
const output = execSync(`node jobs/cancelJob.js ${projectId} ${jobId}`);
144+
assert.include(output, 'state:');
145+
assert.include(output, 'errorResult: null');
146+
});
147+
148+
it('should create a job', async () => {
149+
const output = execSync(`node jobs/createJob.js ${projectId}`);
150+
assert.include(output, 'Rows:');
151+
assert.include(output, 'Tromelin Island');
152+
});
153+
});
154+
});

0 commit comments

Comments
 (0)