Batches with small transactions, --dry-run, progress in the output, and idempotent so that it can be rerun if interrupted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # ====================================================================== # Q: How do you write a management command for a large job? # # Batches with small transactions, --dry-run, progress in the output, and # idempotent so that it can be rerun if interrupted. # ====================================================================== class Command(BaseCommand): help = 'Recalculate customer totals' def add_arguments(self, parser): parser.add_argument('--batch-size', type=int, default=1000) parser.add_argument('--dry-run', action='store_true') def handle(self, *args, batch_size, dry_run, **options): qs = Customer.objects.order_by('pk') for i, chunk in enumerate(read_in_chunks(qs, batch_size), 1): if not dry_run: with transaction.atomic(): recalc_totals(chunk) self.stdout.write(f'batch {i} done') |