diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a660ee..862c8b3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to Merlin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.0b4] + +### Added +- Backwards compatibility for `run_complete` entries in the database + ## [2.0.0b3] ### Added diff --git a/merlin/__init__.py b/merlin/__init__.py index d3070469..bd70d2c9 100644 --- a/merlin/__init__.py +++ b/merlin/__init__.py @@ -14,7 +14,7 @@ import sys -__version__ = "2.0.0b3" +__version__ = "2.0.0b4" VERSION = __version__ PATH_TO_PROJ = os.path.join(os.path.dirname(__file__), "") diff --git a/merlin/backends/utils.py b/merlin/backends/utils.py index 7f3ae9bf..3e00dae8 100644 --- a/merlin/backends/utils.py +++ b/merlin/backends/utils.py @@ -73,7 +73,7 @@ def serialize_entity(entity: T) -> Dict[str, str]: Returns: A dictionary of information that the database can interpret. """ - LOG.debug("Deserializing data...") + LOG.debug("Serializing data...") serialized_data = {} for field in entity.get_instance_fields(): @@ -90,7 +90,7 @@ def serialize_entity(entity: T) -> Dict[str, str]: else: serialized_data[field.name] = str(field_value) - LOG.debug("Successfully deserialized data.") + LOG.debug("Successfully serialized data.") return serialized_data diff --git a/merlin/db_scripts/data_models.py b/merlin/db_scripts/data_models.py index 013681e1..a938d24d 100644 --- a/merlin/db_scripts/data_models.py +++ b/merlin/db_scripts/data_models.py @@ -105,6 +105,15 @@ def from_dict(cls: Type[T], data: Dict) -> T: Returns: An instance of the dataclass that called this. """ + # Handle backwards compatibility between 2.0.0b2 and 2.0.0b3: migrate run_complete to run_status + if "run_complete" in data and "run_status" not in data: + run_complete = data.pop("run_complete") + # Map the boolean to an appropriate status + data["run_status"] = RunStatus.COMPLETED.value if run_complete else RunStatus.RUNNING.value + elif "run_complete" in data and "run_status" in data: + # Remove run_complete if both keys exist to avoid conflicts + data.pop("run_complete") + return cls(**data) @classmethod diff --git a/merlin/db_scripts/entities/run_entity.py b/merlin/db_scripts/entities/run_entity.py index 9bea4bc2..682f6985 100644 --- a/merlin/db_scripts/entities/run_entity.py +++ b/merlin/db_scripts/entities/run_entity.py @@ -218,6 +218,37 @@ def is_finished(self) -> bool: """ return self.get_run_status() in (RunStatus.COMPLETED, RunStatus.CANCELLED, RunStatus.FAILED) + @property + def run_complete(self) -> bool: + """ + Backwards compatibility property for old code/databases using run_complete. + + Returns: + True if the run has completed (successfully or otherwise), False otherwise. + + Deprecated: Use run_status instead. + """ + return self.is_finished() + + @run_complete.setter + def run_complete(self, value: bool): + """ + Backwards compatibility setter for old code using run_complete. + Maps boolean values to the appropriate run_status. + + Deprecated: Use run_status instead. + """ + if value: + # If setting to complete and current status is not already a terminal state, + # default to COMPLETED + if self.get_run_status() not in (RunStatus.COMPLETED, RunStatus.FAILED, RunStatus.CANCELLED): + self.set_run_status(RunStatus.COMPLETED) + else: + # If setting to not complete, assume RUNNING + # (unless it's already in a terminal state, which would be odd) + if self.get_run_status() in (RunStatus.COMPLETED, RunStatus.FAILED, RunStatus.CANCELLED): + self.set_run_status(RunStatus.RUNNING) + def get_metadata_file(self) -> str: """ Get the path to the metadata file for this run.