diff --git a/migrate.py b/migrate.py new file mode 100644 index 00000000..7e46bb76 --- /dev/null +++ b/migrate.py @@ -0,0 +1,15 @@ +from flask_migrate import upgrade + +from webapp.app import app +from webapp.context import database_lock + + +def migrate() -> None: + # Use lock to prevent multiple concurrent migrations on startup + # Automatically upgrade to head revision + with app.app_context(), database_lock(): + upgrade() + + +if __name__ == "__main__": + migrate() \ No newline at end of file diff --git a/rockcraft.yaml b/rockcraft.yaml index cc011bd1..cc4dfc99 100644 --- a/rockcraft.yaml +++ b/rockcraft.yaml @@ -20,6 +20,7 @@ parts: - flask/app/.env - flask/app/app.py - flask/app/data + - flask/app/migrate.py - flask/app/migrations - flask/app/webapp - flask/app/templates diff --git a/webapp/site_repository.py b/webapp/site_repository.py index 7b9ff60a..2d0bf09a 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -2,6 +2,7 @@ import re import subprocess import time +import traceback from collections.abc import Callable from pathlib import Path from typing import TypedDict @@ -265,19 +266,18 @@ def get_tree_from_db(self): tree = get_tree_struct(db.session, webpages) # If the tree is empty, load from the repository if not tree or ( - tree.get("children") and not tree.get("parent_id") + not tree.get("children") and not tree.get("parent_id") ): msg = ( "Reloading incomplete tree root " - f"{self.repository_uri}." + f"{self.repository_uri}. {tree}" ) self.logger.info( msg, ) tree = self.get_new_tree() return tree - # Raise an error if the project does not exist. - raise SiteRepositoryError("Invalid project_id. Unable to load tree.") + return None def get_tree(self, no_cache: bool = False): """Get the tree from the cache or load a new tree to cache and db.""" @@ -403,14 +403,15 @@ def get_tree_sync(self, no_cache: bool = False): self.invalidate_cache() # Load the tree from database - try: - tree = self.get_tree_from_db() + if tree := self.get_tree_from_db(): self.logger.info(f"Tree refreshed for {self.repository_uri}") - # Update the cache - self.set_tree_in_cache(tree) + try: + # Update the cache + self.set_tree_in_cache(tree) + except Exception as e: + self.logger.exception(traceback.format_exc()) + self.logger.error(f"Unable to save tree to cache: {e}") return tree - except Exception as e: - self.logger.error(f"Error loading tree: {e}") # Or just return an empty tree return {