@@ -377,6 +377,48 @@ def ensure_uploads_log_columns():
377377 conn .commit ()
378378#==================================================#
379379
380+ def dedupe_uploads_log ():
381+ """Remove duplicate (property,tab,filename) rows and enforce unique index."""
382+ with sqlite3 .connect (DB_NAME ) as conn :
383+ c = conn .cursor ()
384+ # Try best: keep by uploaded_at desc, then rowid desc (needs window functions)
385+ try :
386+ c .executescript ("""
387+ WITH ranked AS (
388+ SELECT rowid,
389+ property, tab, filename,
390+ COALESCE(uploaded_at,'') AS ts,
391+ ROW_NUMBER() OVER (
392+ PARTITION BY property, tab, filename
393+ ORDER BY ts DESC, rowid DESC
394+ ) AS rn
395+ FROM uploads_log
396+ )
397+ DELETE FROM uploads_log
398+ WHERE rowid IN (SELECT rowid FROM ranked WHERE rn > 1);
399+ """ )
400+ except sqlite3 .OperationalError :
401+ # Fallback for older SQLite: keep MAX(rowid)
402+ c .execute ("""
403+ DELETE FROM uploads_log
404+ WHERE rowid NOT IN (
405+ SELECT MAX(rowid)
406+ FROM uploads_log
407+ GROUP BY property, tab, filename
408+ );
409+ """ )
410+ # Enforce uniqueness
411+ try :
412+ c .execute ("""
413+ CREATE UNIQUE INDEX IF NOT EXISTS idx_uploads_unique
414+ ON uploads_log(property, tab, filename)
415+ """ )
416+ except sqlite3 .OperationalError as e :
417+ # If this fails, we’ll at least not crash the app
418+ current_app .logger .warning ("unique index create failed: %s" , e )
419+ conn .commit ()
420+ #==================================================#
421+
380422def auto_log_material_files ():
381423 """
382424 Walk UPLOAD_FOLDER and upsert one row per (property, tab, filename).
@@ -531,18 +573,16 @@ def _run_startup_tasks():
531573 return
532574 try :
533575 ensure_uploads_log_schema ()
534- ensure_uploads_log_columns ()
535576 except Exception as e :
536- app .logger .warning ("ensure_uploads_log_schema/columns skipped: %s" , e )
537- # try:
538- # auto_import_uploads()
539- # except Exception as e:
540- # app.logger.warning("auto_import_uploads skipped: %s", e)
541- # try:
542- # auto_log_material_files()
543- # except Exception as e:
544- # app.logger.warning("auto_log_material_files skipped: %s", e)
545-
577+ app .logger .warning ("ensure_uploads_log_schema: %s" , e )
578+ try :
579+ ensure_uploads_log_columns ()
580+ except Exception as e :
581+ app .logger .warning ("ensure_uploads_log_columns: %s" , e )
582+ try :
583+ dedupe_uploads_log ()
584+ except Exception as e :
585+ app .logger .warning ("dedupe_uploads_log: %s" , e )
546586 _startup_done = True
547587
548588@app .before_request
0 commit comments