diff --git a/AUTHORS b/AUTHORS index 0c0fed8e4ad..60175e8852d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -78,6 +78,7 @@ answer newbie questions, and generally made Django that much better: brut.alll@gmail.com btoll@bestweb.net Jonathan Buchanan + Keith Bussell Juan Manuel Caicedo Trevor Caira Ricardo Javier Cárdenes Medina diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index d06b131d6f9..193bb26ccf8 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -32,6 +32,7 @@ class Command(BaseCommand): # Keep a count of the installed objects and fixtures fixture_count = 0 object_count = 0 + objects_per_fixture = [] models = set() humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' @@ -60,11 +61,16 @@ class Command(BaseCommand): else: formats = [] - if verbosity >= 2: - if formats: + if formats: + if verbosity > 1: print "Loading '%s' fixtures..." % fixture_name - else: - print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format) + else: + sys.stderr.write( + self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." % + (fixture_name, format))) + transaction.rollback() + transaction.leave_transaction_management() + return if os.path.isabs(fixture_name): fixture_dirs = [fixture_name] @@ -93,6 +99,7 @@ class Command(BaseCommand): return else: fixture_count += 1 + objects_per_fixture.append(0) if verbosity > 0: print "Installing %s fixture '%s' from %s." % \ (format, fixture_name, humanize(fixture_dir)) @@ -100,6 +107,7 @@ class Command(BaseCommand): objects = serializers.deserialize(format, fixture) for obj in objects: object_count += 1 + objects_per_fixture[-1] += 1 models.add(obj.object.__class__) obj.save() label_found = True @@ -117,10 +125,23 @@ class Command(BaseCommand): return fixture.close() except: - if verbosity >= 2: + if verbosity > 1: print "No %s fixture '%s' in %s." % \ (format, fixture_name, humanize(fixture_dir)) + + # If any of the fixtures we loaded contain 0 objects, assume that an + # error was encountered during fixture loading. + if 0 in objects_per_fixture: + sys.stderr.write( + self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" % + (fixture_name))) + transaction.rollback() + transaction.leave_transaction_management() + return + + # If we found even one object in a fixture, we need to reset the + # database sequences. if object_count > 0: sequence_sql = connection.ops.sequence_reset_sql(self.style, models) if sequence_sql: @@ -128,12 +149,12 @@ class Command(BaseCommand): print "Resetting sequences" for line in sequence_sql: cursor.execute(line) - + transaction.commit() transaction.leave_transaction_management() if object_count == 0: - if verbosity >= 2: + if verbosity > 1: print "No fixtures found." else: if verbosity > 0: diff --git a/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn new file mode 100644 index 00000000000..a8b0a0c56cc --- /dev/null +++ b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn @@ -0,0 +1 @@ +This data shouldn't load, as it's of an unknown file format. \ No newline at end of file diff --git a/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml new file mode 100644 index 00000000000..87b809fbc63 --- /dev/null +++ b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml @@ -0,0 +1,7 @@ + + + + Poker on TV is great! + 2006-06-16 11:00:00 + + \ No newline at end of file diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index 144debe05a4..59fc167d50b 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -71,4 +71,27 @@ __test__ = {'API_TESTS':""" >>> Absolute.load_count 1 +############################################### +# Test for ticket #4371 -- fixture loading fails silently in testcases +# Validate that error conditions are caught correctly + +# redirect stderr for the next few tests... +>>> import sys +>>> savestderr = sys.stderr +>>> sys.stderr = sys.stdout + +# Loading data of an unknown format should fail +>>> management.call_command('loaddata', 'bad_fixture1.unkn', verbosity=0) +Problem installing fixture 'bad_fixture1': unkn is not a known serialization format. + +# Loading a fixture file with invalid data using explicit filename +>>> management.call_command('loaddata', 'bad_fixture2.xml', verbosity=0) +No fixture data found for 'bad_fixture2'. (File format may be invalid.) + +# Loading a fixture file with invalid data without file extension +>>> management.call_command('loaddata', 'bad_fixture2', verbosity=0) +No fixture data found for 'bad_fixture2'. (File format may be invalid.) + +>>> sys.stderr = savestderr + """}