"""Re-date images whose post's date arrived after they were linked. #4431. The native ingesters import a post's media before its record, and the date travels in the record (`_post.json`). Every natively downloaded image was therefore linked to an undated post and kept its download time in both gallery date columns, while the post itself was dated correctly. The importer now re-dates a post's images when its record lands; this repairs the images that landed before that. Both columns get back the rules the importer keeps: * `effective_date` is the primary post's date (left alone when that post has none, as the importer does); * `earliest_post_date` is the earliest dated post the image is linked to. Only rows that differ are written. The downgrade does nothing: the old values were download times that no one chose. Revision ID: 0113 Revises: 0112 Create Date: 2026-09-25 """ import sqlalchemy as sa from alembic import op revision = "0113" down_revision = "0112" branch_labels = None depends_on = None def redate_images(conn) -> None: """The data step, on a plain connection, so a test can run it directly.""" conn.execute(sa.text(""" UPDATE image_record ir SET effective_date = p.post_date FROM post p WHERE p.id = ir.primary_post_id AND p.post_date IS NOT NULL AND ir.effective_date IS DISTINCT FROM p.post_date """)) conn.execute(sa.text(""" UPDATE image_record ir SET earliest_post_date = m.earliest FROM ( SELECT ip.image_record_id, MIN(p.post_date) AS earliest FROM image_provenance ip JOIN post p ON p.id = ip.post_id WHERE p.post_date IS NOT NULL GROUP BY ip.image_record_id ) m WHERE m.image_record_id = ir.id AND ir.earliest_post_date IS DISTINCT FROM m.earliest """)) def upgrade(): redate_images(op.get_bind()) def downgrade(): pass