Fixed #4371 -- Improved error checking when loading fixtures. Code now catches explicitly named fixture formats that are not supported (e.g, YAML fixtures if you don't have PyYAML installed), and fixtures that are empty (which can happen due to XML tag errors). Thanks to John Shaffer for the suggestion, and Keith Bussell for his work on the fix.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7595 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
8198bfecee
commit
511e01d978
1
AUTHORS
1
AUTHORS
|
@ -78,6 +78,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
brut.alll@gmail.com
|
brut.alll@gmail.com
|
||||||
btoll@bestweb.net
|
btoll@bestweb.net
|
||||||
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
||||||
|
Keith Bussell <kbussell@gmail.com>
|
||||||
Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
|
Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
|
||||||
Trevor Caira <trevor@caira.com>
|
Trevor Caira <trevor@caira.com>
|
||||||
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
|
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
|
||||||
|
|
|
@ -32,6 +32,7 @@ class Command(BaseCommand):
|
||||||
# Keep a count of the installed objects and fixtures
|
# Keep a count of the installed objects and fixtures
|
||||||
fixture_count = 0
|
fixture_count = 0
|
||||||
object_count = 0
|
object_count = 0
|
||||||
|
objects_per_fixture = []
|
||||||
models = set()
|
models = set()
|
||||||
|
|
||||||
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
|
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
|
||||||
|
@ -60,11 +61,16 @@ class Command(BaseCommand):
|
||||||
else:
|
else:
|
||||||
formats = []
|
formats = []
|
||||||
|
|
||||||
if verbosity >= 2:
|
if formats:
|
||||||
if formats:
|
if verbosity > 1:
|
||||||
print "Loading '%s' fixtures..." % fixture_name
|
print "Loading '%s' fixtures..." % fixture_name
|
||||||
else:
|
else:
|
||||||
print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format)
|
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):
|
if os.path.isabs(fixture_name):
|
||||||
fixture_dirs = [fixture_name]
|
fixture_dirs = [fixture_name]
|
||||||
|
@ -93,6 +99,7 @@ class Command(BaseCommand):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
fixture_count += 1
|
fixture_count += 1
|
||||||
|
objects_per_fixture.append(0)
|
||||||
if verbosity > 0:
|
if verbosity > 0:
|
||||||
print "Installing %s fixture '%s' from %s." % \
|
print "Installing %s fixture '%s' from %s." % \
|
||||||
(format, fixture_name, humanize(fixture_dir))
|
(format, fixture_name, humanize(fixture_dir))
|
||||||
|
@ -100,6 +107,7 @@ class Command(BaseCommand):
|
||||||
objects = serializers.deserialize(format, fixture)
|
objects = serializers.deserialize(format, fixture)
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
object_count += 1
|
object_count += 1
|
||||||
|
objects_per_fixture[-1] += 1
|
||||||
models.add(obj.object.__class__)
|
models.add(obj.object.__class__)
|
||||||
obj.save()
|
obj.save()
|
||||||
label_found = True
|
label_found = True
|
||||||
|
@ -117,10 +125,23 @@ class Command(BaseCommand):
|
||||||
return
|
return
|
||||||
fixture.close()
|
fixture.close()
|
||||||
except:
|
except:
|
||||||
if verbosity >= 2:
|
if verbosity > 1:
|
||||||
print "No %s fixture '%s' in %s." % \
|
print "No %s fixture '%s' in %s." % \
|
||||||
(format, fixture_name, humanize(fixture_dir))
|
(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:
|
if object_count > 0:
|
||||||
sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
|
sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
|
||||||
if sequence_sql:
|
if sequence_sql:
|
||||||
|
@ -128,12 +149,12 @@ class Command(BaseCommand):
|
||||||
print "Resetting sequences"
|
print "Resetting sequences"
|
||||||
for line in sequence_sql:
|
for line in sequence_sql:
|
||||||
cursor.execute(line)
|
cursor.execute(line)
|
||||||
|
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
transaction.leave_transaction_management()
|
transaction.leave_transaction_management()
|
||||||
|
|
||||||
if object_count == 0:
|
if object_count == 0:
|
||||||
if verbosity >= 2:
|
if verbosity > 1:
|
||||||
print "No fixtures found."
|
print "No fixtures found."
|
||||||
else:
|
else:
|
||||||
if verbosity > 0:
|
if verbosity > 0:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
This data shouldn't load, as it's of an unknown file format.
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<django-objcts version="1.0">
|
||||||
|
<objct pk="2" model="fixtures.article">
|
||||||
|
<field type="CharField" name="headline">Poker on TV is great!</field>
|
||||||
|
<field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field>
|
||||||
|
</objct>
|
||||||
|
</django-objcts>
|
|
@ -71,4 +71,27 @@ __test__ = {'API_TESTS':"""
|
||||||
>>> Absolute.load_count
|
>>> Absolute.load_count
|
||||||
1
|
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
|
||||||
|
|
||||||
"""}
|
"""}
|
||||||
|
|
Loading…
Reference in New Issue