diff --git a/app/assets/database/queries/__init__.py b/app/assets/database/queries/__init__.py index a44ed04b9..474355f85 100644 --- a/app/assets/database/queries/__init__.py +++ b/app/assets/database/queries/__init__.py @@ -25,6 +25,7 @@ from app.assets.database.queries.asset_info import ( from app.assets.database.queries.cache_state import ( CacheStateRow, bulk_insert_cache_states_ignore_conflicts, + bulk_update_is_missing, bulk_update_needs_verify, delete_assets_by_ids, delete_cache_states_by_ids, @@ -65,6 +66,7 @@ __all__ = [ "bulk_insert_assets", "bulk_insert_cache_states_ignore_conflicts", "bulk_insert_tags_and_meta", + "bulk_update_is_missing", "bulk_update_needs_verify", "delete_asset_info_by_id", "delete_assets_by_ids", diff --git a/app/assets/database/queries/cache_state.py b/app/assets/database/queries/cache_state.py index 39d79e16c..4e6ea4ccc 100644 --- a/app/assets/database/queries/cache_state.py +++ b/app/assets/database/queries/cache_state.py @@ -261,6 +261,21 @@ def bulk_update_needs_verify(session: Session, state_ids: list[int], value: bool return result.rowcount +def bulk_update_is_missing(session: Session, state_ids: list[int], value: bool) -> int: + """Set is_missing flag for multiple cache states. + + Returns: Number of rows updated + """ + if not state_ids: + return 0 + result = session.execute( + sa.update(AssetCacheState) + .where(AssetCacheState.id.in_(state_ids)) + .values(is_missing=value) + ) + return result.rowcount + + def delete_cache_states_by_ids(session: Session, state_ids: list[int]) -> int: """Delete cache states by their IDs. diff --git a/app/assets/scanner.py b/app/assets/scanner.py index e0d5202f1..201967286 100644 --- a/app/assets/scanner.py +++ b/app/assets/scanner.py @@ -7,6 +7,7 @@ from typing import Literal, TypedDict import folder_paths from app.assets.database.queries import ( add_missing_tag_for_asset_id, + bulk_update_is_missing, bulk_update_needs_verify, delete_cache_states_by_ids, delete_orphaned_seed_asset, @@ -154,6 +155,7 @@ def sync_cache_states_with_filesystem( to_set_verify: list[int] = [] to_clear_verify: list[int] = [] stale_state_ids: list[int] = [] + to_mark_missing: list[int] = [] survivors: set[str] = set() for aid, acc in by_asset.items(): @@ -164,6 +166,7 @@ def sync_cache_states_with_filesystem( for s in states: if not s["exists"]: + to_mark_missing.append(s["sid"]) continue if s["fast_ok"] and s["needs_verify"]: to_clear_verify.append(s["sid"]) @@ -195,6 +198,9 @@ def sync_cache_states_with_filesystem( survivors.add(os.path.abspath(s["fp"])) delete_cache_states_by_ids(session, stale_state_ids) + stale_set = set(stale_state_ids) + to_mark_missing = [sid for sid in to_mark_missing if sid not in stale_set] + bulk_update_is_missing(session, to_mark_missing, value=True) bulk_update_needs_verify(session, to_set_verify, value=True) bulk_update_needs_verify(session, to_clear_verify, value=False) diff --git a/app/assets/services/bulk_ingest.py b/app/assets/services/bulk_ingest.py index 87b492aea..88f48c724 100644 --- a/app/assets/services/bulk_ingest.py +++ b/app/assets/services/bulk_ingest.py @@ -18,6 +18,7 @@ from app.assets.database.queries import ( get_cache_states_by_paths_and_asset_ids, get_unreferenced_unhashed_asset_ids, mark_cache_states_missing_outside_prefixes, + restore_cache_states_by_paths, ) from app.assets.helpers import get_utc_now @@ -201,6 +202,7 @@ def batch_insert_seed_assets( bulk_insert_assets(session, asset_rows) bulk_insert_cache_states_ignore_conflicts(session, cache_state_rows) + restore_cache_states_by_paths(session, absolute_path_list) winning_paths = get_cache_states_by_paths_and_asset_ids(session, path_to_asset_id) all_paths_set = set(absolute_path_list)