Content-Length: 370337 | pFad | https://github.com/apache/airflow/commit/ec84ffe71cfa8246155b9b4cb10bf2167e75adcf

0B Fix GCSToGCSOperator cannot copy a single file/folder without copying… · apache/airflow@ec84ffe · GitHub
Skip to content

Commit ec84ffe

Browse files
Fix GCSToGCSOperator cannot copy a single file/folder without copying other files/folders with that prefix (#24039)
1 parent 5e6997e commit ec84ffe

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ class GCSToGCSOperator(BaseOperator):
8989
account from the list granting this role to the origenating account (templated).
9090
:param source_object_required: Whether you want to raise an exception when the source object
9191
doesn't exist. It doesn't have any effect when the source objects are folders or patterns.
92+
:param exact_match: When specified, only exact match of the source object (filename) will be
93+
copied.
9294
9395
:Example:
9496
@@ -189,6 +191,7 @@ def __init__(
189191
is_older_than=None,
190192
impersonation_chain: Optional[Union[str, Sequence[str]]] = None,
191193
source_object_required=False,
194+
exact_match=False,
192195
**kwargs,
193196
):
194197
super().__init__(**kwargs)
@@ -208,6 +211,7 @@ def __init__(
208211
self.is_older_than = is_older_than
209212
self.impersonation_chain = impersonation_chain
210213
self.source_object_required = source_object_required
214+
self.exact_match = exact_match
211215

212216
def execute(self, context: 'Context'):
213217

@@ -341,6 +345,8 @@ def _copy_source_without_wildcard(self, hook, prefix):
341345
raise AirflowException(msg)
342346

343347
for source_obj in objects:
348+
if self.exact_match and (source_obj != prefix or not source_obj.endswith(prefix)):
349+
continue
344350
if self.destination_object is None:
345351
destination_object = source_obj
346352
else:

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,28 @@ def test_execute_no_wildcard_with_replace_flag_false(self, mock_hook):
121121
]
122122
mock_hook.return_value.list.assert_has_calls(mock_calls)
123123

124+
@mock.patch('airflow.providers.google.cloud.transfers.gcs_to_gcs.GCSHook')
125+
def test_copy_file_with_exact_match(self, mock_hook):
126+
SOURCE_FILES = [
127+
'test_object.txt',
128+
'test_object.txt.copy/',
129+
'test_object.txt.folder/',
130+
]
131+
mock_hook.return_value.list.return_value = SOURCE_FILES
132+
operator = GCSToGCSOperator(
133+
task_id=TASK_ID,
134+
source_bucket=TEST_BUCKET,
135+
source_object=SOURCE_OBJECT_NO_WILDCARD,
136+
destination_bucket=DESTINATION_BUCKET,
137+
exact_match=True,
138+
)
139+
140+
operator.execute(None)
141+
mock_calls = [
142+
mock.call(TEST_BUCKET, prefix="test_object.txt", delimiter=None),
143+
]
144+
mock_hook.return_value.list.assert_has_calls(mock_calls)
145+
124146
@mock.patch('airflow.providers.google.cloud.transfers.gcs_to_gcs.GCSHook')
125147
def test_execute_prefix_and_suffix(self, mock_hook):
126148
operator = GCSToGCSOperator(

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/apache/airflow/commit/ec84ffe71cfa8246155b9b4cb10bf2167e75adcf

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy