Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit 4e3f86e

Browse files
Feature/add quota project option (#1345)
* add ability to specify quota project in profile --------- Co-authored-by: Mike Alfare <[email protected]>
1 parent a09a8fa commit 4e3f86e

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Features
2+
body: Adds the ability to set optional `quota_project` in profile
3+
time: 2024-09-11T23:48:59.767649+01:00
4+
custom:
5+
Author: jcarpenter12
6+
Issue: 1343 1344

dbt/adapters/bigquery/connections.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import google.auth.exceptions
1818
import google.cloud.bigquery
1919
import google.cloud.exceptions
20-
from google.api_core import retry, client_info
20+
from google.api_core import retry, client_info, client_options
2121
from google.auth import impersonated_credentials
2222
from google.oauth2 import (
2323
credentials as GoogleCredentials,
@@ -125,6 +125,7 @@ class BigQueryCredentials(Credentials):
125125
database: Optional[str] = None
126126
schema: Optional[str] = None
127127
execution_project: Optional[str] = None
128+
quota_project: Optional[str] = None
128129
location: Optional[str] = None
129130
priority: Optional[Priority] = None
130131
maximum_bytes_billed: Optional[int] = None
@@ -408,14 +409,17 @@ def get_credentials(cls, profile_credentials):
408409
def get_bigquery_client(cls, profile_credentials):
409410
creds = cls.get_credentials(profile_credentials)
410411
execution_project = profile_credentials.execution_project
412+
quota_project = profile_credentials.quota_project
411413
location = getattr(profile_credentials, "location", None)
412414

413415
info = client_info.ClientInfo(user_agent=f"dbt-bigquery-{dbt_version.version}")
416+
options = client_options.ClientOptions(quota_project_id=quota_project)
414417
return google.cloud.bigquery.Client(
415418
execution_project,
416419
creds,
417420
location=location,
418421
client_info=info,
422+
client_options=options,
419423
)
420424

421425
@classmethod
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
3+
import pytest
4+
5+
from dbt.tests.util import run_dbt
6+
7+
_QUOTA_PROJECT = os.getenv("BIGQUERY_TEST_ALT_DATABASE")
8+
9+
10+
class TestNoQuotaProject:
11+
def test_no_quota_project(self, project):
12+
results = run_dbt()
13+
for result in results:
14+
assert None == result.adapter_response["quota_project"]
15+
16+
17+
class TestQuotaProjectOption:
18+
@pytest.fixture(scope="class")
19+
def profiles_config_update(self, dbt_profile_target):
20+
outputs = {"default": dbt_profile_target}
21+
outputs["default"]["quota_project"] = _QUOTA_PROJECT
22+
yield
23+
24+
def test_quota_project_option(self, project):
25+
results = run_dbt()
26+
for result in results:
27+
assert _QUOTA_PROJECT == result.adapter_response["quota_project"]

tests/unit/test_bigquery_adapter.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,15 +386,17 @@ def test_cancel_open_connections_single(self):
386386
adapter.connections.thread_connections.update({key: master, 1: model})
387387
self.assertEqual(len(list(adapter.cancel_open_connections())), 1)
388388

389+
@patch("dbt.adapters.bigquery.impl.google.api_core.client_options.ClientOptions")
389390
@patch("dbt.adapters.bigquery.impl.google.auth.default")
390391
@patch("dbt.adapters.bigquery.impl.google.cloud.bigquery")
391-
def test_location_user_agent(self, mock_bq, mock_auth_default):
392+
def test_location_user_agent(self, mock_bq, mock_auth_default, MockClientOptions):
392393
creds = MagicMock()
393394
mock_auth_default.return_value = (creds, MagicMock())
394395
adapter = self.get_adapter("loc")
395396

396397
connection = adapter.acquire_connection("dummy")
397398
mock_client = mock_bq.Client
399+
mock_client_options = MockClientOptions.return_value
398400

399401
mock_client.assert_not_called()
400402
connection.handle
@@ -403,6 +405,7 @@ def test_location_user_agent(self, mock_bq, mock_auth_default):
403405
creds,
404406
location="Luna Station",
405407
client_info=HasUserAgent(),
408+
client_options=mock_client_options,
406409
)
407410

408411

0 commit comments

Comments
 (0)