Skip to content

Backfill existing sound files to generated names, as a resumable command #991

Open

Description

@vjpixel

Refactoring Proposal

Follow-up to #699. #982 makes new sound uploads land at sounds/<uuid>.<ext>, but says nothing about the rows already in the database, which still point at files stored under the name their uploader chose. Those are the ones actually exposed today.

#699 asks for "a migration to rename all the objects in the current database". This issue proposes doing it as a resumable management command instead.

Describe the design issue(s) you have identified in the code

A data migration is the wrong shape for this work:

  • It renames live objects in S3. A run that dies halfway — a network blip, a throttle, a deploy timeout — leaves rows pointing at keys that no longer exist, and a migration cannot be resumed from where it stopped.
  • It runs inside the deploy, so it cannot be scheduled for a quiet window, rehearsed against a copy, or aborted after the first few rows look wrong.
  • It gives no way to see what would change before anything does.

Which source files are affected to this issue(s)?

  1. src/core/management/commands/ — new command;
  2. src/core/models.py — reuses the sound_file_path helper added in Store sound uploads under a generated name (#699) #982;
  3. src/core/tests/ — tests for the command.

Describe refactoring alternatives to redesign the code

A command with these properties:

  1. Idempotent, so resuming is just running it again: rows whose name already matches sounds/<uuid>.<ext> are skipped.
  2. Safe ordering — write the new object, update the row, then delete the old object. Interrupted at any point, the worst outcome is an orphaned old file, never a row pointing at nothing.
  3. --dry-run to list what would change without touching storage.
  4. --limit N so a first batch can be small and inspected.
  5. Per-row error isolation: a failure is logged with the key and the run continues, rather than aborting and leaving the job half-done with no record of where.
  6. Backfills file_name_original from the old key when it is empty, so the original name is preserved as Save media content with random names #699 asks.

Blocked on #982, which introduces the sound_file_path helper the command needs so backfilled names match new ones.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions