Commit 3aed485a by Clinton Blackburn

Merge pull request #409 from edx/multi-tenancy/delete-baskets-in-batches

Batching basket deletions
parents 63bc776d 518a688d
...@@ -5,6 +5,7 @@ These baskets don't have much value once the order is placed, and unnecessarily ...@@ -5,6 +5,7 @@ These baskets don't have much value once the order is placed, and unnecessarily
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.management import BaseCommand from django.core.management import BaseCommand
from django.db import transaction
from oscar.core.loading import get_model from oscar.core.loading import get_model
Basket = get_model('basket', 'Basket') Basket = get_model('basket', 'Basket')
...@@ -14,6 +15,12 @@ class Command(BaseCommand): ...@@ -14,6 +15,12 @@ class Command(BaseCommand):
help = 'Delete baskets for which orders have been placed.' help = 'Delete baskets for which orders have been placed.'
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('-b', '--batch-size',
action='store',
dest='batch_size',
default=1000,
type=int,
help='Size of each batch of baskets to be deleted.')
parser.add_argument('--commit', parser.add_argument('--commit',
action='store_true', action='store_true',
dest='commit', dest='commit',
...@@ -25,9 +32,19 @@ class Command(BaseCommand): ...@@ -25,9 +32,19 @@ class Command(BaseCommand):
count = queryset.count() count = queryset.count()
if options['commit']: if options['commit']:
self.stderr.write('Deleting [{}] baskets...'.format(count)) if count:
queryset.delete() self.stderr.write('Deleting [{}] baskets...'.format(count))
self.stderr.write('Done.') batch_size = options['batch_size']
max_id = queryset.order_by('-id')[0].id
for start in range(0, max_id, batch_size):
end = min(start + batch_size, max_id)
self.stderr.write('...deleting baskets [{start}] through [{end}]...'.format(start=start, end=end))
with transaction.atomic():
queryset.filter(pk__gte=start, pk__lte=end).delete()
self.stderr.write('Done.')
else:
self.stderr.write('No baskets to delete.')
else: else:
msg = 'This is a dry run. Had the --commit flag been included, [{}] baskets would have been deleted.'. \ msg = 'This is a dry run. Had the --commit flag been included, [{}] baskets would have been deleted.'. \
format(count) format(count)
......
...@@ -31,7 +31,7 @@ class DeleteOrderedBasketsCommandTests(TestCase): ...@@ -31,7 +31,7 @@ class DeleteOrderedBasketsCommandTests(TestCase):
self.assertEqual(Basket.objects.count(), expected) self.assertEqual(Basket.objects.count(), expected)
# Verify the number of baskets expected to be deleted was printed to stderr # Verify the number of baskets expected to be deleted was printed to stderr
expected = 'This is a dry run. Had the --commit flag been included, [{}] baskets would have been deleted.'.\ expected = 'This is a dry run. Had the --commit flag been included, [{}] baskets would have been deleted.'. \
format(len(self.orders)) format(len(self.orders))
self.assertEqual(out.getvalue().strip(), expected) self.assertEqual(out.getvalue().strip(), expected)
...@@ -48,5 +48,17 @@ class DeleteOrderedBasketsCommandTests(TestCase): ...@@ -48,5 +48,17 @@ class DeleteOrderedBasketsCommandTests(TestCase):
self.assertEqual(list(Basket.objects.all()), self.unordered_baskets) self.assertEqual(list(Basket.objects.all()), self.unordered_baskets)
# Verify info was output to stderr # Verify info was output to stderr
expected = 'Deleting [{}] baskets...\nDone.'.format(len(self.orders)) actual = out.getvalue().strip()
self.assertEqual(out.getvalue().strip(), expected) self.assertTrue(actual.startswith('Deleting [{}] baskets...'.format(len(self.orders))))
self.assertTrue(actual.endswith('Done.'))
def test_commit_without_baskets(self):
""" Verify the command does nothing if there are no baskets to delete. """
# Delete all baskets
Basket.objects.all().delete()
# Call the command with the commit flag
out = StringIO()
call_command(self.command, commit=True, stderr=out)
self.assertEqual(out.getvalue().strip(), 'No baskets to delete.')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment