#768 steps 1+2: normalized image_prediction table (read cutover) #92
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Normalize tagger predictions out of the
image_record.tagger_predictionsJSON blob into a queryableimage_predictiontable (#768), through the read cutover. Verify-before-drop: this is steps 1+2 only — thetagger_predictionscolumn is still present (vestigial, dual-written); the column DROP + dual-write removal + prune retirement is a held step-3 follow-up.image_predictiontable (image_record_id, raw_name, category, score), migration 0045 creates it + backfills from the JSON via a single set-basedINSERT…SELECT json_each, filtered to>= ml_settings.tagger_store_floor(0.70) so it's self-sufficient — does NOT need the #764 prune (which is superseded; it was too slow rewriting 100 GB in place and failing at its soft limit).SuggestionService.for_image/for_selection,apply_allowlist_tags, importer re-import reset. Parity by construction — each loads the same{name:{category,confidence}}shape, so downstream logic is byte-identical. Integration suite confirms.tag_and_embeddual-writes the table (transitional).Deploy needs NO ml-worker quiesce (0045 takes no
ACCESS EXCLUSIVEon image_record). DB stays ~100 GB until step 3 (column drop + VACUUM FULL).CI green on dev
75eab18(run 845).🤖 Generated with Claude Code
Switch every prediction READER off the JSON column onto the normalized image_prediction table. Parity by construction: each reader loads the same {raw_name: {category, confidence}} dict it consumed before (via small _load_predictions helpers), so all downstream threshold/alias/merge/consensus logic is byte-identical — only the data source changed. - suggestions.SuggestionService.for_image (and for_selection via it) - ml.apply_allowlist_tags (iterates images that have prediction rows) - importer re-import reset deletes the image's prediction rows The tagger_predictions JSON column is still dual-written (step 1) so it stays valid during transition; the backfill task's NULL check still works. Removing the JSON write + DROP column + retiring the #764 prune is the cleanup follow-up (needs a quiesced-worker window for the DROP lock). Tests: shared tests/_prediction_helpers.seed_predictions seeds the table; read-path tests (suggestions, bulk consensus, allowlist apply, API) seed there instead of ImageRecord.tagger_predictions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>