fix: user-feedback-on-schema-mismatch (#1558)

* validate schema version on restore

* show user error on backup failure
This commit is contained in:
Hayden
2022-08-14 11:06:35 -08:00
committed by GitHub
parent 7adcc86d03
commit 3985713cbd
4 changed files with 56 additions and 15 deletions

View File

@@ -5,6 +5,8 @@ from pathlib import Path
class BackupContents:
_tables: dict = None
def __init__(self, file: Path) -> None:
self.base = file
self.data_directory = self.base / "data"
@@ -22,9 +24,22 @@ class BackupContents:
return True
def schema_version(self) -> str:
tables = self.read_tables()
alembic_version = tables.get("alembic_version", [])
if not alembic_version:
return ""
return alembic_version[0].get("version_num", "")
def read_tables(self) -> dict:
with open(self.tables) as f:
return json.loads(f.read())
if self._tables is None:
with open(self.tables, "r") as f:
self._tables = json.load(f)
return self._tables
class BackupFile:

View File

@@ -9,6 +9,10 @@ from mealie.services.backups_v2.alchemy_exporter import AlchemyExporter
from mealie.services.backups_v2.backup_file import BackupFile
class BackupSchemaMismatch(Exception):
...
class BackupV2(BaseService):
def __init__(self, db_url: str = None) -> None:
super().__init__()
@@ -73,18 +77,28 @@ class BackupV2(BaseService):
self._postgres()
with backup as contents:
# ================================
# Validation
if not contents.validate():
self.logger.error(
"Invalid backup file. file does not contain required elements (data directory and database.json"
)
raise ValueError("Invalid backup file")
# Purge the Database
database_json = contents.read_tables()
if not AlchemyExporter.validate_schemas(database_json, self.db_exporter.dump()):
self.logger.error("Invalid backup file. Database schemas do not match")
raise BackupSchemaMismatch("Invalid backup file. Database schemas do not match")
# ================================
# Purge Database
self.logger.info("dropping all database tables")
self.db_exporter.drop_all()
database_json = contents.read_tables()
# ================================
# Restore Database
self.logger.info("importing database tables")
self.db_exporter.restore(database_json)