Skip to content

Commit 72d0f86

Browse files
committed
fix(assets): refresh loader_path when re-ingesting an existing reference
upsert_reference only wrote loader_path on the INSERT branch, so re-ingesting an existing reference (an output overwritten in place, or a file re-registered after its loader_path derivation changed) kept the stale or NULL value forever. Write it on the UPDATE branch too, with a null-safe change guard so a loader_path difference alone is enough to trigger the update, and identical values stay a no-op.
1 parent 0908613 commit 72d0f86

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

app/assets/database/queries/asset_reference.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,13 +688,14 @@ def upsert_reference(
688688
AssetReference.asset_id != asset_id,
689689
AssetReference.mtime_ns.is_(None),
690690
AssetReference.mtime_ns != int(mtime_ns),
691+
AssetReference.loader_path.is_distinct_from(loader_path),
691692
AssetReference.is_missing == True, # noqa: E712
692693
AssetReference.deleted_at.isnot(None),
693694
)
694695
)
695696
.values(
696-
asset_id=asset_id, mtime_ns=int(mtime_ns), is_missing=False,
697-
deleted_at=None, updated_at=now,
697+
asset_id=asset_id, mtime_ns=int(mtime_ns), loader_path=loader_path,
698+
is_missing=False, deleted_at=None, updated_at=now,
698699
)
699700
)
700701
res2 = session.execute(upd)

tests-unit/assets_test/queries/test_cache_state.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,39 @@ def test_upsert_scenarios(
176176
ref = session.query(AssetReference).filter_by(file_path=file_path).one()
177177
assert ref.mtime_ns == final_mtime
178178

179+
def test_upsert_refreshes_loader_path_on_existing_reference(self, session: Session):
180+
"""Re-ingesting an existing reference writes the loader_path computed
181+
by that ingest, healing NULL or stale values even when nothing else
182+
about the row changed."""
183+
asset = _make_asset(session, "hash1")
184+
file_path = "/models/checkpoints/sub/model.safetensors"
185+
186+
upsert_reference(
187+
session, asset_id=asset.id, file_path=file_path, name="model",
188+
mtime_ns=100, loader_path=None,
189+
)
190+
session.commit()
191+
192+
created, updated = upsert_reference(
193+
session, asset_id=asset.id, file_path=file_path, name="model",
194+
mtime_ns=100, loader_path="sub/model.safetensors",
195+
)
196+
session.commit()
197+
198+
assert created is False
199+
assert updated is True
200+
ref = session.query(AssetReference).filter_by(file_path=file_path).one()
201+
assert ref.loader_path == "sub/model.safetensors"
202+
203+
# Identical loader_path is a no-op, not a spurious update.
204+
created, updated = upsert_reference(
205+
session, asset_id=asset.id, file_path=file_path, name="model",
206+
mtime_ns=100, loader_path="sub/model.safetensors",
207+
)
208+
session.commit()
209+
assert created is False
210+
assert updated is False
211+
179212
def test_upsert_restores_missing_reference(self, session: Session):
180213
"""Upserting a reference that was marked missing should restore it."""
181214
asset = _make_asset(session, "hash1")

0 commit comments

Comments
 (0)