Skip to content

Commit d19985a

Browse files
committed
BigQuery parameterized query sample
Splits named and positional query samples into separate functions.
1 parent 4361e74 commit d19985a

File tree

4 files changed

+105
-55
lines changed

4 files changed

+105
-55
lines changed

bigquery/cloud-client/async_query_params.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
"""Command-line application to perform asynchronous queries in BigQuery.
17+
"""Command-line app to perform async queries with parameters in BigQuery.
1818
1919
For more information, see the README.md under /bigquery.
2020
2121
Example invocation:
22-
$ python async_query_params.py 'romeoandjuliet' 100
22+
$ python async_query_params.py --use-named-params 'romeoandjuliet' 100
23+
$ python async_query_params.py --use-positional-params 'romeoandjuliet' 100
2324
"""
2425

2526
import argparse
@@ -39,7 +40,23 @@ def wait_for_job(job):
3940
time.sleep(1)
4041

4142

42-
def async_query_params(corpus, min_word_count):
43+
def print_results(query_results):
44+
"""Print the query results by requesting a page at a time."""
45+
page_token = None
46+
47+
while True:
48+
rows, total_rows, page_token = query_results.fetch_data(
49+
max_results=10,
50+
page_token=page_token)
51+
52+
for row in rows:
53+
print(row)
54+
55+
if not page_token:
56+
break
57+
58+
59+
def async_query_positional_params(corpus, min_word_count):
4360
client = bigquery.Client()
4461
query_job = client.run_async_query(
4562
str(uuid.uuid4()),
@@ -64,8 +81,11 @@ def async_query_params(corpus, min_word_count):
6481
query_job.use_legacy_sql = False
6582
query_job.begin()
6683
wait_for_job(query_job)
67-
print('Positional parameter query completed')
84+
print_results(query_job.results())
6885

86+
87+
def async_query_named_params(corpus, min_word_count):
88+
client = bigquery.Client()
6989
query_job = client.run_async_query(
7090
str(uuid.uuid4()),
7191
"""SELECT word, word_count
@@ -83,22 +103,14 @@ def async_query_params(corpus, min_word_count):
83103
query_job.use_legacy_sql = False
84104
query_job.begin()
85105
wait_for_job(query_job)
86-
print('Named parameter query completed')
87-
88-
# Print the query results by requesting a page at a time.
89-
query_results = query_job.results()
90-
page_token = None
91-
92-
while True:
93-
rows, total_rows, page_token = query_results.fetch_data(
94-
max_results=10,
95-
page_token=page_token)
106+
print_results(query_job.results())
96107

97-
for row in rows:
98-
print(row)
99108

100-
if not page_token:
101-
break
109+
def main(use_named_params=False, corpus='romeoandjuliet', min_word_count=100):
110+
if use_named_params:
111+
async_query_named_params(corpus, min_word_count)
112+
else:
113+
async_query_positional_params(corpus, min_word_count)
102114

103115

104116
if __name__ == '__main__':
@@ -113,6 +125,15 @@ def async_query_params(corpus, min_word_count):
113125
help='Minimum count of words to query.',
114126
type=int)
115127

128+
params_type_parser = parser.add_mutually_exclusive_group(required=False)
129+
params_type_parser.add_argument(
130+
'--use-named-params',
131+
dest='use_named_params',
132+
action='store_true')
133+
params_type_parser.add_argument(
134+
'--use-positional-params',
135+
dest='use_named_params',
136+
action='store_false')
137+
parser.set_defaults(use_named_params=False)
116138
args = parser.parse_args()
117-
118-
async_query_params(args.corpus, args.min_word_count)
139+
main(args.use_named_params, args.corpus, args.min_word_count)

bigquery/cloud-client/async_query_params_test.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from sync_query import sync_query
15+
from async_query_params import main
1616

1717

18-
def test_sync_query(cloud_config, capsys):
19-
sync_query('romeoandjuliet', 100)
20-
18+
def test_main_use_named_params(cloud_config, capsys):
19+
main(use_named_params=True, corpus='romeoandjuliet', min_word_count=100)
2120
out, _ = capsys.readouterr()
21+
assert 'love' in out
2222

23-
assert 'Positional parameter query completed' in out
24-
assert 'Named parameter query completed' in out
23+
24+
def test_main_use_positional_params(cloud_config, capsys):
25+
main(use_named_params=False, corpus='romeoandjuliet', min_word_count=100)
26+
out, _ = capsys.readouterr()
2527
assert 'love' in out

bigquery/cloud-client/sync_query_params.py

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,37 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
"""Command-line application to perform synchronous queries in BigQuery.
17+
"""Command-line app to perform synchronous queries with parameters in BigQuery.
1818
1919
For more information, see the README.md under /bigquery.
2020
2121
Example invocation:
22-
$ python sync_query_params.py 'romeoandjuliet' 100
22+
$ python sync_query_params.py --use-named-params 'romeoandjuliet' 100
23+
$ python sync_query_params.py --use-positional-params 'romeoandjuliet' 100
2324
"""
2425

2526
import argparse
2627

27-
# [START sync_query_params]
2828
from google.cloud import bigquery
2929

3030

31-
def sync_query_params(corpus, min_word_count):
31+
def print_results(query_results):
32+
"""Print the query results by requesting a page at a time."""
33+
page_token = None
34+
35+
while True:
36+
rows, total_rows, page_token = query_results.fetch_data(
37+
max_results=10,
38+
page_token=page_token)
39+
40+
for row in rows:
41+
print(row)
42+
43+
if not page_token:
44+
break
45+
46+
47+
def sync_query_positional_params(corpus, min_word_count):
3248
client = bigquery.Client()
3349
query_results = client.run_sync_query(
3450
"""SELECT word, word_count
@@ -38,15 +54,24 @@ def sync_query_params(corpus, min_word_count):
3854
ORDER BY word_count DESC;
3955
""",
4056
query_parameters=(
41-
bigquery.ScalarQueryParameter(None, 'STRING', corpus),
57+
bigquery.ScalarQueryParameter(
58+
# Set the name to None to use positional parameters (? symbol
59+
# in the query). Note that you cannot mix named and positional
60+
# parameters.
61+
None,
62+
'STRING',
63+
corpus),
4264
bigquery.ScalarQueryParameter(None, 'INT64', min_word_count)))
4365

4466
# Only standard SQL syntax supports parameters in queries.
4567
# See: https://cloud.google.com/bigquery/sql-reference/
4668
query_results.use_legacy_sql = False
4769
query_results.run()
48-
print('Positional parameter query completed')
70+
print_results(query_results)
4971

72+
73+
def sync_query_named_params(corpus, min_word_count):
74+
client = bigquery.Client()
5075
query_results = client.run_sync_query(
5176
"""SELECT word, word_count
5277
FROM `bigquery-public-data.samples.shakespeare`
@@ -62,23 +87,14 @@ def sync_query_params(corpus, min_word_count):
6287
min_word_count)))
6388
query_results.use_legacy_sql = False
6489
query_results.run()
65-
print('Named parameter query completed')
90+
print_results(query_results)
6691

67-
# Print the query results by requesting a page at a time.
68-
page_token = None
6992

70-
while True:
71-
rows, total_rows, page_token = query_results.fetch_data(
72-
max_results=10,
73-
page_token=page_token)
74-
75-
for row in rows:
76-
print(row)
77-
78-
if not page_token:
79-
break
80-
81-
# [END sync_query_params]
93+
def main(use_named_params=False, corpus='romeoandjuliet', min_word_count=100):
94+
if use_named_params:
95+
sync_query_named_params(corpus, min_word_count)
96+
else:
97+
sync_query_positional_params(corpus, min_word_count)
8298

8399

84100
if __name__ == '__main__':
@@ -93,6 +109,15 @@ def sync_query_params(corpus, min_word_count):
93109
help='Minimum count of words to query.',
94110
type=int)
95111

112+
params_type_parser = parser.add_mutually_exclusive_group(required=False)
113+
params_type_parser.add_argument(
114+
'--use-named-params',
115+
dest='use_named_params',
116+
action='store_true')
117+
params_type_parser.add_argument(
118+
'--use-positional-params',
119+
dest='use_named_params',
120+
action='store_false')
121+
parser.set_defaults(use_named_params=False)
96122
args = parser.parse_args()
97-
98-
sync_query_params(args.corpus, args.min_word_count)
123+
main(args.use_named_params, args.corpus, args.min_word_count)

bigquery/cloud-client/sync_query_params_test.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from sync_query import sync_query
15+
from sync_query_params import main
1616

1717

18-
def test_sync_query(cloud_config, capsys):
19-
sync_query('romeoandjuliet', 100)
20-
18+
def test_main_use_named_params(cloud_config, capsys):
19+
main(use_named_params=True, corpus='romeoandjuliet', min_word_count=100)
2120
out, _ = capsys.readouterr()
21+
assert 'love' in out
2222

23-
assert 'Positional parameter query completed' in out
24-
assert 'Named parameter query completed' in out
23+
24+
def test_main_use_positional_params(cloud_config, capsys):
25+
main(use_named_params=False, corpus='romeoandjuliet', min_word_count=100)
26+
out, _ = capsys.readouterr()
2527
assert 'love' in out

0 commit comments

Comments
 (0)