fix: stop scan crashing on duplicate file hashes
scan.py used scalar_one_or_none() to test whether any other photo shared the same file_hash, but that helper raises MultipleResultsFound the moment 2+ rows match — i.e. exactly the duplicate case it was trying to flag. Every file beyond the second copy bombed out with "Multiple rows were found when one or none was required" and was left in the failed bucket. Replace with a COUNT(*) > 0 check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import json
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
from celery import shared_task
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
import aiofiles
|
||||
import redis
|
||||
@@ -172,10 +172,21 @@ async def _scan_folder_async(folder_path: str, source_root_id: Optional[str], ta
|
||||
# Calculate file hash for duplicate detection
|
||||
file_hash = await calculate_file_hash(filepath)
|
||||
|
||||
# Check for duplicate by hash
|
||||
duplicate = await session.execute(
|
||||
select(Photo).where(Photo.file_hash == file_hash)
|
||||
) if file_hash else None
|
||||
# Check for duplicate by hash. We only care
|
||||
# whether *any* other photo shares this hash, so
|
||||
# use a count rather than scalar_one_or_none()
|
||||
# which raises "Multiple rows were found" the
|
||||
# moment the library has 2+ copies of the same
|
||||
# file (i.e. exactly the case we're trying to
|
||||
# flag).
|
||||
is_dup = False
|
||||
if file_hash:
|
||||
dup_count = (await session.execute(
|
||||
select(func.count(Photo.id)).where(
|
||||
Photo.file_hash == file_hash
|
||||
)
|
||||
)).scalar() or 0
|
||||
is_dup = dup_count > 0
|
||||
|
||||
# Create photo entry
|
||||
photo = Photo(
|
||||
@@ -188,7 +199,7 @@ async def _scan_folder_async(folder_path: str, source_root_id: Optional[str], ta
|
||||
file_size=stat.st_size,
|
||||
taken_at=datetime.fromtimestamp(stat.st_mtime),
|
||||
taken_at_source='filesystem',
|
||||
is_duplicate=bool(duplicate.scalar_one_or_none() if duplicate else False),
|
||||
is_duplicate=is_dup,
|
||||
processing_status='pending'
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user