Skip to content

Commit 02976be

Browse files
authored
Refactor: BigQuery to GCS Operator (#22506)
1 parent 02526b3 commit 02976be

3 files changed

Lines changed: 24 additions & 50 deletions

File tree

airflow/providers/google/cloud/hooks/bigquery.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ def run_copy(
19051905
def run_extract(
19061906
self,
19071907
source_project_dataset_table: str,
1908-
destination_cloud_storage_uris: str,
1908+
destination_cloud_storage_uris: List[str],
19091909
compression: str = 'NONE',
19101910
export_format: str = 'CSV',
19111911
field_delimiter: str = ',',
@@ -1945,7 +1945,7 @@ def run_extract(
19451945
var_name='source_project_dataset_table',
19461946
)
19471947

1948-
configuration = {
1948+
configuration: Dict[str, Any] = {
19491949
'extract': {
19501950
'sourceTable': {
19511951
'projectId': source_project,
@@ -1956,7 +1956,7 @@ def run_extract(
19561956
'destinationUris': destination_cloud_storage_uris,
19571957
'destinationFormat': export_format,
19581958
}
1959-
} # type: Dict[str, Any]
1959+
}
19601960

19611961
if labels:
19621962
configuration['labels'] = labels

airflow/providers/google/cloud/transfers/bigquery_to_gcs.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
# under the License.
1818
"""This module contains Google BigQuery to Google Cloud Storage operator."""
1919
import warnings
20-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union
21-
22-
from google.cloud.bigquery.table import TableReference
20+
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Union
2321

2422
from airflow.models import BaseOperator
2523
from airflow.providers.google.cloud.hooks.bigquery import BigQueryHook
@@ -128,26 +126,12 @@ def execute(self, context: 'Context'):
128126
location=self.location,
129127
impersonation_chain=self.impersonation_chain,
130128
)
131-
132-
table_ref = TableReference.from_string(self.source_project_dataset_table, hook.project_id)
133-
134-
configuration: Dict[str, Any] = {
135-
'extract': {
136-
'sourceTable': table_ref.to_api_repr(),
137-
'compression': self.compression,
138-
'destinationUris': self.destination_cloud_storage_uris,
139-
'destinationFormat': self.export_format,
140-
}
141-
}
142-
143-
if self.labels:
144-
configuration['labels'] = self.labels
145-
146-
if self.export_format == 'CSV':
147-
# Only set fieldDelimiter and printHeader fields if using CSV.
148-
# Google does not like it if you set these fields for other export
149-
# formats.
150-
configuration['extract']['fieldDelimiter'] = self.field_delimiter
151-
configuration['extract']['printHeader'] = self.print_header
152-
153-
hook.insert_job(configuration=configuration)
129+
hook.run_extract(
130+
source_project_dataset_table=self.source_project_dataset_table,
131+
destination_cloud_storage_uris=self.destination_cloud_storage_uris,
132+
compression=self.compression,
133+
export_format=self.export_format,
134+
field_delimiter=self.field_delimiter,
135+
print_header=self.print_header,
136+
labels=self.labels,
137+
)

tests/providers/google/cloud/transfers/test_bigquery_to_gcs.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,17 @@
2727
PROJECT_ID = 'test-project-id'
2828

2929

30-
class TestBigQueryToCloudStorageOperator(unittest.TestCase):
30+
class TestBigQueryToGCSOperator(unittest.TestCase):
3131
@mock.patch('airflow.providers.google.cloud.transfers.bigquery_to_gcs.BigQueryHook')
3232
def test_execute(self, mock_hook):
33-
source_project_dataset_table = f'{TEST_DATASET}.{TEST_TABLE_ID}'
33+
source_project_dataset_table = f'{PROJECT_ID}:{TEST_DATASET}.{TEST_TABLE_ID}'
3434
destination_cloud_storage_uris = ['gs://some-bucket/some-file.txt']
3535
compression = 'NONE'
3636
export_format = 'CSV'
3737
field_delimiter = ','
3838
print_header = True
3939
labels = {'k1': 'v1'}
4040

41-
mock_hook().project_id = PROJECT_ID
42-
43-
configuration = {
44-
'extract': {
45-
'sourceTable': {
46-
'projectId': mock_hook().project_id,
47-
'datasetId': TEST_DATASET,
48-
'tableId': TEST_TABLE_ID,
49-
},
50-
'compression': compression,
51-
'destinationUris': destination_cloud_storage_uris,
52-
'destinationFormat': export_format,
53-
'fieldDelimiter': field_delimiter,
54-
'printHeader': print_header,
55-
},
56-
'labels': labels,
57-
}
58-
5941
operator = BigQueryToGCSOperator(
6042
task_id=TASK_ID,
6143
source_project_dataset_table=source_project_dataset_table,
@@ -69,4 +51,12 @@ def test_execute(self, mock_hook):
6951

7052
operator.execute(None)
7153

72-
mock_hook.return_value.insert_job.assert_called_once_with(configuration=configuration)
54+
mock_hook.return_value.run_extract.assert_called_once_with(
55+
source_project_dataset_table=source_project_dataset_table,
56+
destination_cloud_storage_uris=destination_cloud_storage_uris,
57+
compression=compression,
58+
export_format=export_format,
59+
field_delimiter=field_delimiter,
60+
print_header=print_header,
61+
labels=labels,
62+
)

0 commit comments

Comments
 (0)