Skip to content

Commit cfde08b

Browse files
Marthe Van Den Hendetomasfarias
authored andcommitted
add support for full_refresh in template_fields
1 parent 093de55 commit cfde08b

8 files changed

Lines changed: 131 additions & 5 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repos:
88
name: Ensure end of file newline
99

1010
- repo: https://github.com/pre-commit/mirrors-mypy
11-
rev: v1.1.1
11+
rev: v1.15.0
1212
hooks:
1313
- id: mypy
1414
name: Static type checking

airflow_dbt_python/operators/dbt.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,9 @@ class DbtRunOperator(DbtBaseOperator):
399399
https://docs.getdbt.com/reference/commands/run.
400400
"""
401401

402-
template_fields = base_template_fields + selection_template_fields
402+
template_fields = (
403+
base_template_fields + selection_template_fields + ["full_refresh"]
404+
)
403405

404406
def __init__(
405407
self,
@@ -431,7 +433,9 @@ class DbtSeedOperator(DbtBaseOperator):
431433
https://docs.getdbt.com/reference/commands/seed.
432434
"""
433435

434-
template_fields = base_template_fields + selection_template_fields
436+
template_fields = (
437+
base_template_fields + selection_template_fields + ["full_refresh"]
438+
)
435439

436440
def __init__(
437441
self,
@@ -500,7 +504,9 @@ class DbtCompileOperator(_GraphRunnableOperator):
500504
https://docs.getdbt.com/reference/commands/compile.
501505
"""
502506

503-
template_fields = base_template_fields + selection_template_fields
507+
template_fields = (
508+
base_template_fields + selection_template_fields + ["full_refresh"]
509+
)
504510

505511
def __init__(
506512
self,
@@ -765,7 +771,9 @@ class DbtBuildOperator(DbtBaseOperator):
765771
https://docs.getdbt.com/reference/commands/build.
766772
"""
767773

768-
template_fields = base_template_fields + selection_template_fields
774+
template_fields = (
775+
base_template_fields + selection_template_fields + ["full_refresh"]
776+
)
769777

770778
def __init__(
771779
self,

airflow_dbt_python/utils/configs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ class TableMutabilityConfig(SelectionConfig):
618618
def __post_init__(self):
619619
"""Call superclass __post_init__."""
620620
super().__post_init__()
621+
if isinstance(self.full_refresh, str):
622+
self.full_refresh = self.full_refresh.lower() == "true"
621623

622624

623625
@dataclasses.dataclass

tests/operators/test_dbt_build.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,24 @@ def test_dbt_build_models_with_project_from_s3(
234234
build_result = execution_results["results"][0]
235235

236236
assert build_result["status"] == RunStatus.Success
237+
238+
239+
def test_full_refresh_in_template_fields():
240+
"""Test that full_refresh is included in DbtBuildOperator template_fields."""
241+
assert "full_refresh" in DbtBuildOperator.template_fields
242+
243+
244+
def test_full_refresh_templated():
245+
"""Test that full_refresh can be templated with Jinja."""
246+
import pendulum
247+
from airflow.models.dag import DAG
248+
249+
dag = DAG(dag_id="test_dag", start_date=pendulum.datetime(2025, 1, 1))
250+
op = DbtBuildOperator(
251+
task_id="dbt_task",
252+
full_refresh="{{ params.full_refresh }}",
253+
dag=dag,
254+
)
255+
context = {"params": {"full_refresh": "True"}}
256+
op.render_template_fields(context)
257+
assert op.full_refresh == "True"

tests/operators/test_dbt_compile.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,24 @@ def test_dbt_compile_uses_correct_argument_according_to_version():
206206
assert getattr(op, "models", None) is None
207207
assert op.selector == "a-selector"
208208
assert getattr(op, "selector_name", None) is None
209+
210+
211+
def test_full_refresh_in_template_fields():
212+
"""Test that full_refresh is included in DbtCompileOperator template_fields."""
213+
assert "full_refresh" in DbtCompileOperator.template_fields
214+
215+
216+
def test_full_refresh_templated():
217+
"""Test that full_refresh can be templated with Jinja."""
218+
import pendulum
219+
from airflow.models.dag import DAG
220+
221+
dag = DAG(dag_id="test_dag", start_date=pendulum.datetime(2025, 1, 1))
222+
op = DbtCompileOperator(
223+
task_id="dbt_task",
224+
full_refresh="{{ params.full_refresh }}",
225+
dag=dag,
226+
)
227+
context = {"params": {"full_refresh": "True"}}
228+
op.render_template_fields(context)
229+
assert op.full_refresh == "True"

tests/operators/test_dbt_run.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,23 @@ def test_dbt_run_with_airflow_connection_and_profile(
428428
assert run_result["status"] == RunStatus.Success
429429
assert op.profiles_dir == profiles_file.parent
430430
assert execution_results["args"]["target"] == conn_id or target
431+
432+
433+
def test_full_refresh_in_template_fields():
434+
"""Test that full_refresh is included in DbtRunOperator template_fields."""
435+
assert "full_refresh" in DbtRunOperator.template_fields
436+
437+
438+
def test_full_refresh_templated():
439+
"""Test that full_refresh can be templated with Jinja."""
440+
from airflow.models.dag import DAG
441+
442+
dag = DAG(dag_id="test_dag", start_date=pendulum.datetime(2025, 1, 1))
443+
op = DbtRunOperator(
444+
task_id="dbt_task",
445+
full_refresh="{{ params.full_refresh }}",
446+
dag=dag,
447+
)
448+
context = {"params": {"full_refresh": "True"}}
449+
op.render_template_fields(context)
450+
assert op.full_refresh == "True"

tests/operators/test_dbt_seed.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,24 @@ def test_dbt_seed_with_airflow_connection_and_profile(
327327
assert run_result["status"] == RunStatus.Success
328328
assert op.profiles_dir == profiles_file.parent
329329
assert execution_results["args"]["target"] == conn_id or target
330+
331+
332+
def test_full_refresh_in_template_fields():
333+
"""Test that full_refresh is included in DbtSeedOperator template_fields."""
334+
assert "full_refresh" in DbtSeedOperator.template_fields
335+
336+
337+
def test_full_refresh_templated():
338+
"""Test that full_refresh can be templated with Jinja."""
339+
import pendulum
340+
from airflow.models.dag import DAG
341+
342+
dag = DAG(dag_id="test_dag", start_date=pendulum.datetime(2025, 1, 1))
343+
op = DbtSeedOperator(
344+
task_id="dbt_task",
345+
full_refresh="{{ params.full_refresh }}",
346+
dag=dag,
347+
)
348+
context = {"params": {"full_refresh": "True"}}
349+
op.render_template_fields(context)
350+
assert op.full_refresh == "True"

tests/utils/test_configs.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,36 @@ def test_base_config_does_not_override_when_value_in_environment(
506506
)
507507
assert config.fail_fast is None
508508
assert config.require_generic_test_arguments_property is None
509+
510+
511+
def test_table_mutability_config_full_refresh_string_coercion(
512+
profiles_file, dbt_project_file
513+
):
514+
"""Test that full_refresh string values are coerced to booleans."""
515+
config = RunTaskConfig(
516+
profiles_dir=profiles_file.parent,
517+
project_dir=dbt_project_file.parent,
518+
full_refresh="True",
519+
)
520+
assert config.full_refresh is True
521+
522+
config = RunTaskConfig(
523+
profiles_dir=profiles_file.parent,
524+
project_dir=dbt_project_file.parent,
525+
full_refresh="False",
526+
)
527+
assert config.full_refresh is False
528+
529+
config = RunTaskConfig(
530+
profiles_dir=profiles_file.parent,
531+
project_dir=dbt_project_file.parent,
532+
full_refresh=None,
533+
)
534+
assert config.full_refresh is None
535+
536+
config = RunTaskConfig(
537+
profiles_dir=profiles_file.parent,
538+
project_dir=dbt_project_file.parent,
539+
full_refresh=True,
540+
)
541+
assert config.full_refresh is True

0 commit comments

Comments
 (0)