diff --git a/src/logic/database/Crud.py b/src/logic/database/Crud.py index d60e7fee1870779286969fa0f4affcd5275fa559..4f4a4a69ba378478b3043dde5bcb2befd171d312 100644 --- a/src/logic/database/Crud.py +++ b/src/logic/database/Crud.py @@ -137,6 +137,13 @@ def get_latest_measurement_for_sensor(db: Session, sensorId: int) -> Models.Meas .first() +def get_first_measurement_for_sensor(db: Session, sensorId: int) -> Models.Measurement: + return db.query(Models.Measurement) \ + .filter(Models.Measurement.sensor_id == sensorId) \ + .order_by(Models.Measurement.timestamp.asc()) \ + .first() + + def get_measurement(db: Session, measurementId: int) -> Models.Measurement: return db.query(Models.Measurement).filter(Models.Measurement.id == measurementId).first() diff --git a/src/logic/database/DatabaseCleaner.py b/src/logic/database/DatabaseCleaner.py index b4d99b1add885e0bf410450f08d327bda43ef20a..3cb0200ad68eceb3fac8982d49868c4375499ea0 100644 --- a/src/logic/database/DatabaseCleaner.py +++ b/src/logic/database/DatabaseCleaner.py @@ -30,8 +30,14 @@ class DatabaseCleaner: LOGGER.debug(f'Cleaning measurements for sensor "{sensor.name}" ' f'(id: {sensor.id}, device_id: {sensor.device_id})') + firstMeasurement = Crud.get_first_measurement_for_sensor(db=db, sensorId=sensor.id) + if firstMeasurement is None: + continue + + minDate = datetime.strptime(firstMeasurement.timestamp, Crud.DATE_FORMAT).date() + processedDate = policyStart - while processedDate > self.MIN_DATE: + while processedDate > minDate: LOGGER.debug(f'Cleaning {processedDate.strftime("%Y-%m-%d")}...') measurementIds, idsToDelete = DatabaseCleaner._categorize_measurements_for_day(db, date=processedDate, diff --git a/src/test/DatabaseCleanerTest.py b/src/test/DatabaseCleanerTest.py index ffdfcf5f344167dd7a8298b62daad925626151ac..026c96db54e10716a82f8331c6440f901f1f4dcc 100644 --- a/src/test/DatabaseCleanerTest.py +++ b/src/test/DatabaseCleanerTest.py @@ -58,6 +58,10 @@ class TestRetentionPolicy(unittest.TestCase): class TestDatabaseCleaner(unittest.TestCase): + FIRST_MEASUREMENT = Schemas.Measurement(id=0, value=18, sensor_id=1, + timestamp=datetime(year=2021, month=8, day=1, + hour=22, minute=45, second=0).strftime(DATE_FORMAT)) + MEASUREMENT1 = Schemas.Measurement(id=1, value=5, sensor_id=1, timestamp=datetime(year=2021, month=8, day=18, hour=6, minute=55, second=0).strftime(DATE_FORMAT)) @@ -225,6 +229,7 @@ class TestDatabaseCleaner(unittest.TestCase): mockedCrud.get_measurements_for_sensor.side_effect = self.get_measurements_mocked mockedCrud.get_sensors.return_value = [Schemas.Sensor(id=1, name="myTempSensor", type="temperature", device_id=1)] + mockedCrud.get_first_measurement_for_sensor.return_value = self.FIRST_MEASUREMENT database = Mock() from logic.database.DatabaseCleaner import DatabaseCleaner @@ -235,6 +240,9 @@ class TestDatabaseCleaner(unittest.TestCase): mockedCrud.delete_multiple_measurements.assert_called_once_with(database, {3}) + calls = mockedCrud.get_measurements_for_sensor.call_args_list + self.assertNotIn((database, '2020-01-01 00:00:00', '2020-01-01 06:00:00', 1), [call.args for call in calls]) + def test_onePolicy_deleteMeasurements_twoSensors(self): mockedCrud = Mock() with patch.dict('sys.modules', **{'logic.database.Crud': mockedCrud}): @@ -244,6 +252,7 @@ class TestDatabaseCleaner(unittest.TestCase): type="temperature", device_id=1), Schemas.Sensor(id=2, name="myHumiditySensor", type="humidity", device_id=1)] + mockedCrud.get_first_measurement_for_sensor.return_value = self.FIRST_MEASUREMENT database = Mock() from logic.database.DatabaseCleaner import DatabaseCleaner @@ -257,5 +266,4 @@ class TestDatabaseCleaner(unittest.TestCase): self.assertEqual((database, {3}), calls[0].args) self.assertEqual((database, {5}), calls[1].args) - # TODO: test: multiple policies