Skip to content

Commit 01b42d4

Browse files
authored
Merge pull request #52 from alonme/always-use-provided-project-id
Use the provided project_id when using a service account
2 parents c3baf5f + acada63 commit 01b42d4

File tree

3 files changed

+23
-18
lines changed

3 files changed

+23
-18
lines changed

pybigquery/parse_url.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def parse_url(url):
2929
# maximum_billing_tier (deprecated)
3030
if 'maximum_billing_tier' in query: raise ValueError("maximum_billing_tier is a deprecated argument")
3131

32+
project_id = url.host
3233
location = None
3334
dataset_id = url.database or None
3435
arraysize = None
@@ -55,9 +56,9 @@ def parse_url(url):
5556
# if a dataset_id exists, we need to return a job_config that isn't None
5657
# so it can be updated with a dataset reference from the client
5758
if dataset_id:
58-
return location, dataset_id, arraysize, credentials_path, QueryJobConfig()
59+
return project_id, location, dataset_id, arraysize, credentials_path, QueryJobConfig()
5960
else:
60-
return location, dataset_id, arraysize, credentials_path, None
61+
return project_id, location, dataset_id, arraysize, credentials_path, None
6162

6263
job_config = QueryJobConfig()
6364

@@ -169,4 +170,4 @@ def parse_url(url):
169170
except AttributeError:
170171
raise ValueError("invalid write_disposition in url query: " + query['write_disposition'])
171172

172-
return location, dataset_id, arraysize, credentials_path, job_config
173+
return project_id, location, dataset_id, arraysize, credentials_path, job_config

pybigquery/sqlalchemy_bigquery.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,33 +288,35 @@ def dbapi(cls):
288288
def _add_default_dataset_to_job_config(job_config, project_id, dataset_id):
289289
# If dataset_id is set, then we know the job_config isn't None
290290
if dataset_id:
291-
# If project_id is missing, use default project_id
291+
# If project_id is missing, use default project_id for the current environment
292292
if not project_id:
293293
_, project_id = auth.default()
294294

295295
job_config.default_dataset = '{}.{}'.format(project_id, dataset_id)
296296

297297

298-
def _create_client_from_credentials(self, credentials, default_query_job_config):
298+
def _create_client_from_credentials(self, credentials, default_query_job_config, project_id):
299+
if project_id is None:
300+
project_id = credentials.project_id
301+
299302
scopes = (
300303
'https://www.googleapis.com/auth/bigquery',
301304
'https://www.googleapis.com/auth/cloud-platform',
302305
'https://www.googleapis.com/auth/drive'
303306
)
304307
credentials = credentials.with_scopes(scopes)
305308

306-
self._add_default_dataset_to_job_config(default_query_job_config,
307-
credentials.project_id, self.dataset_id)
309+
self._add_default_dataset_to_job_config(default_query_job_config, project_id, self.dataset_id)
308310

309311
return bigquery.Client(
310-
project=credentials.project_id,
312+
project=project_id,
311313
credentials=credentials,
312314
location=self.location,
313315
default_query_job_config=default_query_job_config,
314316
)
315317

316318
def create_connect_args(self, url):
317-
location, dataset_id, arraysize, credentials_path, default_query_job_config = parse_url(url)
319+
project_id, location, dataset_id, arraysize, credentials_path, default_query_job_config = parse_url(url)
318320

319321
self.arraysize = self.arraysize or arraysize
320322
self.location = location or self.location
@@ -323,18 +325,17 @@ def create_connect_args(self, url):
323325

324326
if self.credentials_path:
325327
credentials = service_account.Credentials.from_service_account_file(self.credentials_path)
326-
client = self._create_client_from_credentials(credentials, default_query_job_config)
328+
client = self._create_client_from_credentials(credentials, default_query_job_config, project_id)
327329

328330
elif self.credentials_info:
329331
credentials = service_account.Credentials.from_service_account_info(self.credentials_info)
330-
client = self._create_client_from_credentials(credentials, default_query_job_config)
332+
client = self._create_client_from_credentials(credentials, default_query_job_config, project_id)
331333

332334
else:
333-
self._add_default_dataset_to_job_config(default_query_job_config,
334-
url.host, dataset_id)
335+
self._add_default_dataset_to_job_config(default_query_job_config, project_id, dataset_id)
335336

336337
client = bigquery.Client(
337-
project=url.host,
338+
project=project_id,
338339
location=self.location,
339340
default_query_job_config=default_query_job_config
340341
)

test/test_parse_url.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ def url_with_everything():
4646

4747

4848
def test_basic(url_with_everything):
49-
location, dataset_id, arraysize, credentials_path, job_config = parse_url(url_with_everything)
49+
project_id, location, dataset_id, arraysize, credentials_path, job_config = parse_url(url_with_everything)
5050

51+
assert project_id == 'some-project'
5152
assert location == 'some-location'
5253
assert dataset_id == 'some-dataset'
5354
assert arraysize == 1000
@@ -68,7 +69,7 @@ def test_basic(url_with_everything):
6869
('write_disposition', 'WRITE_APPEND'),
6970
])
7071
def test_all_values(url_with_everything, param, value):
71-
job_config = parse_url(url_with_everything)[4]
72+
job_config = parse_url(url_with_everything)[5]
7273

7374
config_value = getattr(job_config, param)
7475
if callable(value):
@@ -108,8 +109,9 @@ def test_empty_url():
108109

109110
def test_empty_with_non_config():
110111
url = parse_url(make_url('bigquery:///?location=some-location&arraysize=1000&credentials_path=/some/path/to.json'))
111-
location, dataset_id, arraysize, credentials_path, job_config = url
112+
project_id, location, dataset_id, arraysize, credentials_path, job_config = url
112113

114+
assert project_id is None
113115
assert location == 'some-location'
114116
assert dataset_id is None
115117
assert arraysize == 1000
@@ -118,8 +120,9 @@ def test_empty_with_non_config():
118120

119121
def test_only_dataset():
120122
url = parse_url(make_url('bigquery:///some-dataset'))
121-
location, dataset_id, arraysize, credentials_path, job_config = url
123+
project_id, location, dataset_id, arraysize, credentials_path, job_config = url
122124

125+
assert project_id is None
123126
assert location is None
124127
assert dataset_id == 'some-dataset'
125128
assert arraysize is None

0 commit comments

Comments
 (0)