Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MAINTENANCE] Make Validation definitions immutable #9606

Merged
merged 13 commits into from
Mar 11, 2024
28 changes: 5 additions & 23 deletions great_expectations/core/validation_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from great_expectations._docs_decorators import public_api
from great_expectations.compatibility.pydantic import (
BaseModel,
PrivateAttr,
Field,
ValidationError,
validator,
)
Expand All @@ -15,9 +15,6 @@
ExpectationSuite,
expectationSuiteSchema,
)
from great_expectations.data_context.store.validation_config_store import (
ValidationConfigStore, # noqa: TCH001
)
from great_expectations.validator.v1_validator import ResultFormat, Validator

if TYPE_CHECKING:
Expand Down Expand Up @@ -87,6 +84,7 @@ class Config:
arbitrary_types_allowed = (
True # Necessary for compatibility with suite's Marshmallow dep
)
validate_assignment = True
"""
When serialized, the suite and data fields should be encoded as a set of identifiers.
These will be used as foreign keys to retrieve the actual objects from the appropriate stores.
Expand Down Expand Up @@ -120,18 +118,11 @@ class Config:
BatchConfig: lambda b: _encode_data(b),
}

name: str
data: BatchConfig # TODO: Should support a union of Asset | BatchConfig
suite: ExpectationSuite
name: str = Field(..., allow_mutation=False)
data: BatchConfig = Field(..., allow_mutation=False)
suite: ExpectationSuite = Field(..., allow_mutation=False)
id: Union[str, None] = None

# private attributes that must be set immediately after instantiation
_store: ValidationConfigStore = PrivateAttr()

def __init__(self, **data: Any):
super().__init__(**data)
self._store = project_manager.get_validation_config_store()

@validator("suite", pre=True)
def _validate_suite(cls, v: dict | ExpectationSuite):
# Input will be a dict of identifiers if being deserialized or a suite object if being constructed by a user.
Expand Down Expand Up @@ -233,12 +224,3 @@ def run(
result_format=result_format,
)
return validator.validate_expectation_suite(self.suite, evaluation_parameters)

@public_api
def save(self) -> None:
key = self._store.get_key(name=self.name, id=self.id)

try:
self._store.update(key=key, value=self)
except gx_exceptions.StoreBackendError:
raise ValueError("ValidationConfig must be added to a store before saving.")
Comment on lines -237 to -244
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

save() is an update method so we no longer need it (or the store dep)

25 changes: 0 additions & 25 deletions tests/core/test_validation_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,28 +497,3 @@ def test_validation_config_deserialization_non_existant_resource(
):
with pytest.raises(ValueError, match=f"{error_substring}*."):
ValidationConfig.parse_obj(serialized_config)


@pytest.mark.unit
def test_validation_config_save_success(
ephemeral_context: EphemeralDataContext, validation_config: ValidationConfig
):
context = ephemeral_context
vc = validation_config

vc = context.validations.add(vc)

other_suite = ExpectationSuite(name="my_other_suite")
vc.suite = other_suite
vc.save()

assert vc.suite == other_suite
assert context.validations.get(vc.name).suite == other_suite


@pytest.mark.unit
def test_validation_config_save_failure(validation_config: ValidationConfig):
with pytest.raises(
ValueError, match="ValidationConfig must be added to a store before saving."
):
validation_config.save()