a1f2b3c4d5e6_backfill_owner_roles.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. """backfill owner roles for existing investigations
  2. Revision ID: a1f2b3c4d5e6
  3. Revises: bac5764d4496
  4. Create Date: 2026-04-11 00:00:00.000000
  5. """
  6. from typing import Sequence, Union
  7. from uuid import uuid4
  8. from alembic import op
  9. import sqlalchemy as sa
  10. import json
  11. # revision identifiers, used by Alembic.
  12. revision: str = "a1f2b3c4d5e6"
  13. down_revision: Union[str, None] = "bac5764d4496"
  14. branch_labels: Union[str, Sequence[str], None] = None
  15. depends_on: Union[str, Sequence[str], None] = None
  16. def upgrade() -> None:
  17. """Insert OWNER role entry for every investigation that lacks one."""
  18. conn = op.get_bind()
  19. # Find investigations with no entry in investigation_user_roles
  20. rows = conn.execute(
  21. sa.text(
  22. """
  23. SELECT i.id, i.owner_id
  24. FROM investigations i
  25. LEFT JOIN investigation_user_roles r
  26. ON r.investigation_id = i.id AND r.user_id = i.owner_id
  27. WHERE r.id IS NULL
  28. AND i.owner_id IS NOT NULL
  29. """
  30. )
  31. ).fetchall()
  32. for inv_id, owner_id in rows:
  33. conn.execute(
  34. sa.text(
  35. """
  36. INSERT INTO investigation_user_roles (id, user_id, investigation_id, roles)
  37. VALUES (:id, :user_id, :investigation_id, :roles)
  38. """
  39. ),
  40. {
  41. "id": str(uuid4()),
  42. "user_id": str(owner_id),
  43. "investigation_id": str(inv_id),
  44. "roles": json.dumps(["owner"]),
  45. },
  46. )
  47. def downgrade() -> None:
  48. """No-op: we don't remove the backfilled rows."""
  49. pass