diff --git a/lifting/importers.py b/lifting/importers.py index 1809016..f373803 100644 --- a/lifting/importers.py +++ b/lifting/importers.py @@ -1,4 +1,5 @@ import sqlite3 +from django.db import transaction from lifting.models import Exercise, Set @@ -23,16 +24,17 @@ def import_fitnotes_db(filename): # map to an Exercise id or str exercise_id_mapping[fnid] = exercises[cleaned] if cleaned in exercises else cleaned - Set.objects.filter(source='fitnotes').delete() - for fnid, date, weight_kg, reps in cur.execute( - 'SELECT exercise_id, date, metric_weight, reps FROM training_log'): + with transaction.atomic(): + Set.objects.filter(source='fitnotes').delete() + for fnid, date, weight_kg, reps in cur.execute( + 'SELECT exercise_id, date, metric_weight, reps FROM training_log'): - # create Exercise if it wasn't found and there's a workout using it - if isinstance(exercise_id_mapping[fnid], str): - exercise_id_mapping[fnid] = Exercise.objects.create( - names=[exercise_id_mapping[fnid]]).id + # create Exercise if it wasn't found and there's a workout using it + if isinstance(exercise_id_mapping[fnid], str): + exercise_id_mapping[fnid] = Exercise.objects.create( + names=[exercise_id_mapping[fnid]]).id - exercise_id = exercise_id_mapping[fnid] + exercise_id = exercise_id_mapping[fnid] - Set.objects.create(exercise_id=exercise_id, date=date, weight_kg=weight_kg, reps=reps, - source='fitnotes') + Set.objects.create(exercise_id=exercise_id, date=date, weight_kg=weight_kg, reps=reps, + source='fitnotes') diff --git a/lifting/testdata/baddata.fitnotes b/lifting/testdata/baddata.fitnotes new file mode 100644 index 0000000..a0de8a8 Binary files /dev/null and b/lifting/testdata/baddata.fitnotes differ diff --git a/lifting/tests.py b/lifting/tests.py index 1892aa8..a82af2d 100644 --- a/lifting/tests.py +++ b/lifting/tests.py @@ -32,3 +32,14 @@ class TestFitnotesImport(TestCase): import_fitnotes_db('lifting/testdata/example.fitnotes') assert Exercise.objects.count() == 2 assert Set.objects.count() == 9 + + def test_bad_import(self): + # good db then bad db, should fail without screwing up existing data + import_fitnotes_db('lifting/testdata/example.fitnotes') + try: + # baddata.fitnotes has all exercise ids set to 9999 + import_fitnotes_db('lifting/testdata/baddata.fitnotes') + except Exception: + pass + assert Exercise.objects.count() == 2 + assert Set.objects.count() == 9