diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py
index f44edf7..078fd6f 100644
|
a
|
b
|
import traceback
|
| 7 | 7 | |
| 8 | 8 | from django.conf import settings |
| 9 | 9 | from django.core import serializers |
| 10 | | from django.core.management.base import BaseCommand |
| | 10 | from django.core.management.base import BaseCommand, CommandError |
| 11 | 11 | from django.core.management.color import no_style |
| 12 | 12 | from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS, |
| 13 | 13 | IntegrityError, DatabaseError) |
| … |
… |
class Command(BaseCommand):
|
| 36 | 36 | connection = connections[using] |
| 37 | 37 | |
| 38 | 38 | if not len(fixture_labels): |
| 39 | | self.stderr.write( |
| | 39 | raise CommandError( |
| 40 | 40 | "No database fixture specified. Please provide the path of at " |
| 41 | 41 | "least one fixture in the command line." |
| 42 | 42 | ) |
| 43 | | return |
| 44 | 43 | |
| 45 | 44 | verbosity = int(options.get('verbosity')) |
| 46 | 45 | show_traceback = options.get('traceback') |
| … |
… |
class Command(BaseCommand):
|
| 126 | 125 | if verbosity >= 2: |
| 127 | 126 | self.stdout.write("Loading '%s' fixtures..." % fixture_name) |
| 128 | 127 | else: |
| 129 | | self.stderr.write( |
| | 128 | raise CommandError( |
| 130 | 129 | "Problem installing fixture '%s': %s is not a known serialization format." % |
| 131 | 130 | (fixture_name, format)) |
| 132 | | if commit: |
| 133 | | transaction.rollback(using=using) |
| 134 | | transaction.leave_transaction_management(using=using) |
| 135 | | return |
| 136 | 131 | |
| 137 | 132 | if os.path.isabs(fixture_name): |
| 138 | 133 | fixture_dirs = [fixture_name] |
| … |
… |
class Command(BaseCommand):
|
| 167 | 162 | else: |
| 168 | 163 | try: |
| 169 | 164 | if label_found: |
| 170 | | self.stderr.write("Multiple fixtures named '%s' in %s. Aborting." % |
| | 165 | raise CommandError("Multiple fixtures named '%s' in %s. Aborting." % |
| 171 | 166 | (fixture_name, humanize(fixture_dir))) |
| 172 | | if commit: |
| 173 | | transaction.rollback(using=using) |
| 174 | | transaction.leave_transaction_management(using=using) |
| 175 | | return |
| 176 | 167 | |
| 177 | 168 | fixture_count += 1 |
| 178 | 169 | objects_in_fixture = 0 |
| … |
… |
class Command(BaseCommand):
|
| 191 | 182 | try: |
| 192 | 183 | obj.save(using=using) |
| 193 | 184 | except (DatabaseError, IntegrityError) as e: |
| 194 | | msg = "Could not load %(app_label)s.%(object_name)s(pk=%(pk)s): %(error_msg)s" % { |
| | 185 | e.args = ("Could not load %(app_label)s.%(object_name)s(pk=%(pk)s): %(error_msg)s" % { |
| 195 | 186 | 'app_label': obj.object._meta.app_label, |
| 196 | 187 | 'object_name': obj.object._meta.object_name, |
| 197 | 188 | 'pk': obj.object.pk, |
| 198 | 189 | 'error_msg': e |
| 199 | | } |
| 200 | | raise e.__class__, e.__class__(msg), sys.exc_info()[2] |
| | 190 | },) |
| | 191 | raise |
| 201 | 192 | |
| 202 | 193 | loaded_object_count += loaded_objects_in_fixture |
| 203 | 194 | fixture_object_count += objects_in_fixture |
| … |
… |
class Command(BaseCommand):
|
| 208 | 199 | # If the fixture we loaded contains 0 objects, assume that an |
| 209 | 200 | # error was encountered during fixture loading. |
| 210 | 201 | if objects_in_fixture == 0: |
| 211 | | self.stderr.write( |
| | 202 | raise CommandError( |
| 212 | 203 | "No fixture data found for '%s'. (File format may be invalid.)" % |
| 213 | 204 | (fixture_name)) |
| 214 | | if commit: |
| 215 | | transaction.rollback(using=using) |
| 216 | | transaction.leave_transaction_management(using=using) |
| 217 | | return |
| 218 | 205 | |
| 219 | 206 | # Since we disabled constraint checks, we must manually check for |
| 220 | 207 | # any invalid keys that might have been added |
| … |
… |
class Command(BaseCommand):
|
| 223 | 210 | |
| 224 | 211 | except (SystemExit, KeyboardInterrupt): |
| 225 | 212 | raise |
| 226 | | except Exception: |
| | 213 | except Exception as e: |
| 227 | 214 | if commit: |
| 228 | 215 | transaction.rollback(using=using) |
| 229 | 216 | transaction.leave_transaction_management(using=using) |
| 230 | | if show_traceback: |
| 231 | | traceback.print_exc() |
| 232 | | else: |
| 233 | | self.stderr.write( |
| 234 | | "Problem installing fixture '%s': %s" % |
| 235 | | (full_path, ''.join(traceback.format_exception(sys.exc_type, |
| 236 | | sys.exc_value, sys.exc_traceback)))) |
| 237 | | return |
| 238 | | |
| | 217 | if not isinstance(e, CommandError): |
| | 218 | e.args = ("Problem installing fixture '%s': %s" % (full_path, e),) |
| | 219 | raise |
| 239 | 220 | |
| 240 | 221 | # If we found even one object in a fixture, we need to reset the |
| 241 | 222 | # database sequences. |
diff --git a/tests/modeltests/fixtures/tests.py b/tests/modeltests/fixtures/tests.py
index 478bbe9..f5176da 100644
|
a
|
b
|
import StringIO
|
| 4 | 4 | |
| 5 | 5 | from django.contrib.sites.models import Site |
| 6 | 6 | from django.core import management |
| 7 | | from django.db import connection |
| | 7 | from django.db import connection, IntegrityError |
| 8 | 8 | from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature |
| 9 | 9 | |
| 10 | 10 | from .models import Article, Book, Spy, Tag, Visa |
| … |
… |
class FixtureLoadingTests(TestCase):
|
| 232 | 232 | |
| 233 | 233 | def test_ambiguous_compressed_fixture(self): |
| 234 | 234 | # The name "fixture5" is ambigous, so loading it will raise an error |
| 235 | | new_io = StringIO.StringIO() |
| 236 | | management.call_command('loaddata', 'fixture5', verbosity=0, stderr=new_io, commit=False) |
| 237 | | output = new_io.getvalue().strip().split('\n') |
| 238 | | self.assertEqual(len(output), 1) |
| 239 | | self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture5'")) |
| | 235 | with self.assertRaisesRegexp(management.CommandError, |
| | 236 | "Multiple fixtures named 'fixture5'"): |
| | 237 | management.call_command('loaddata', 'fixture5', verbosity=0, commit=False) |
| 240 | 238 | |
| 241 | 239 | def test_db_loading(self): |
| 242 | 240 | # Load db fixtures 1 and 2. These will load using the 'default' database identifier implicitly |
| … |
… |
class FixtureLoadingTests(TestCase):
|
| 258 | 256 | # is closed at the end of each test. |
| 259 | 257 | if connection.vendor == 'mysql': |
| 260 | 258 | connection.cursor().execute("SET sql_mode = 'TRADITIONAL'") |
| 261 | | new_io = StringIO.StringIO() |
| 262 | | management.call_command('loaddata', 'invalid.json', verbosity=0, stderr=new_io, commit=False) |
| 263 | | output = new_io.getvalue().strip().split('\n') |
| 264 | | self.assertRegexpMatches(output[-1], "Error: Could not load fixtures.Article\(pk=1\): .*$") |
| | 259 | with self.assertRaisesRegexp(IntegrityError, |
| | 260 | "Could not load fixtures.Article\(pk=1\): .*$"): |
| | 261 | management.call_command('loaddata', 'invalid.json', verbosity=0, commit=False) |
| 265 | 262 | |
| 266 | 263 | def test_loading_using(self): |
| 267 | 264 | # Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly |
| … |
… |
class FixtureTransactionTests(TransactionTestCase):
|
| 316 | 313 | |
| 317 | 314 | # Try to load fixture 2 using format discovery; this will fail |
| 318 | 315 | # because there are two fixture2's in the fixtures directory |
| 319 | | new_io = StringIO.StringIO() |
| 320 | | management.call_command('loaddata', 'fixture2', verbosity=0, stderr=new_io) |
| 321 | | output = new_io.getvalue().strip().split('\n') |
| 322 | | self.assertEqual(len(output), 1) |
| 323 | | self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture2'")) |
| | 316 | with self.assertRaisesRegexp(management.CommandError, |
| | 317 | "Multiple fixtures named 'fixture2'"): |
| | 318 | management.call_command('loaddata', 'fixture2', verbosity=0) |
| 324 | 319 | |
| 325 | 320 | # object list is unaffected |
| 326 | 321 | self.assertQuerysetEqual(Article.objects.all(), [ |
diff --git a/tests/regressiontests/fixtures_regress/tests.py b/tests/regressiontests/fixtures_regress/tests.py
index 0e2cc3a..c0b811b 100644
|
a
|
b
|
from io import BytesIO
|
| 9 | 9 | from django.core import management |
| 10 | 10 | from django.core.management.base import CommandError |
| 11 | 11 | from django.core.management.commands.dumpdata import sort_dependencies |
| 12 | | from django.db import transaction |
| | 12 | from django.db import transaction, IntegrityError |
| 13 | 13 | from django.db.models import signals |
| 14 | 14 | from django.test import (TestCase, TransactionTestCase, skipIfDBFeature, |
| 15 | 15 | skipUnlessDBFeature) |
| … |
… |
class TestFixtures(TestCase):
|
| 116 | 116 | Test for ticket #4371 -- Loading data of an unknown format should fail |
| 117 | 117 | Validate that error conditions are caught correctly |
| 118 | 118 | """ |
| 119 | | stderr = BytesIO() |
| 120 | | management.call_command( |
| 121 | | 'loaddata', |
| 122 | | 'bad_fixture1.unkn', |
| 123 | | verbosity=0, |
| 124 | | commit=False, |
| 125 | | stderr=stderr, |
| 126 | | ) |
| 127 | | self.assertEqual( |
| 128 | | stderr.getvalue(), |
| 129 | | "Problem installing fixture 'bad_fixture1': unkn is not a known serialization format.\n" |
| 130 | | ) |
| | 119 | with self.assertRaisesRegexp(management.CommandError, |
| | 120 | "Problem installing fixture 'bad_fixture1': " |
| | 121 | "unkn is not a known serialization format."): |
| | 122 | management.call_command( |
| | 123 | 'loaddata', |
| | 124 | 'bad_fixture1.unkn', |
| | 125 | verbosity=0, |
| | 126 | commit=False, |
| | 127 | ) |
| 131 | 128 | |
| 132 | 129 | def test_invalid_data(self): |
| 133 | 130 | """ |
| … |
… |
class TestFixtures(TestCase):
|
| 135 | 132 | using explicit filename. |
| 136 | 133 | Validate that error conditions are caught correctly |
| 137 | 134 | """ |
| 138 | | stderr = BytesIO() |
| 139 | | management.call_command( |
| 140 | | 'loaddata', |
| 141 | | 'bad_fixture2.xml', |
| 142 | | verbosity=0, |
| 143 | | commit=False, |
| 144 | | stderr=stderr, |
| 145 | | ) |
| 146 | | self.assertEqual( |
| 147 | | stderr.getvalue(), |
| 148 | | "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" |
| 149 | | ) |
| | 135 | with self.assertRaisesRegexp(management.CommandError, |
| | 136 | "No fixture data found for 'bad_fixture2'. \(File format may be invalid.\)"): |
| | 137 | management.call_command( |
| | 138 | 'loaddata', |
| | 139 | 'bad_fixture2.xml', |
| | 140 | verbosity=0, |
| | 141 | commit=False, |
| | 142 | ) |
| 150 | 143 | |
| 151 | 144 | def test_invalid_data_no_ext(self): |
| 152 | 145 | """ |
| … |
… |
class TestFixtures(TestCase):
|
| 154 | 147 | without file extension. |
| 155 | 148 | Validate that error conditions are caught correctly |
| 156 | 149 | """ |
| 157 | | stderr = BytesIO() |
| 158 | | management.call_command( |
| 159 | | 'loaddata', |
| 160 | | 'bad_fixture2', |
| 161 | | verbosity=0, |
| 162 | | commit=False, |
| 163 | | stderr=stderr, |
| 164 | | ) |
| 165 | | self.assertEqual( |
| 166 | | stderr.getvalue(), |
| 167 | | "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" |
| 168 | | ) |
| | 150 | with self.assertRaisesRegexp(management.CommandError, |
| | 151 | "No fixture data found for 'bad_fixture2'. \(File format may be invalid.\)"): |
| | 152 | management.call_command( |
| | 153 | 'loaddata', |
| | 154 | 'bad_fixture2', |
| | 155 | verbosity=0, |
| | 156 | commit=False, |
| | 157 | ) |
| 169 | 158 | |
| 170 | 159 | def test_empty(self): |
| 171 | 160 | """ |
| 172 | 161 | Test for ticket #4371 -- Loading a fixture file with no data returns an error. |
| 173 | 162 | Validate that error conditions are caught correctly |
| 174 | 163 | """ |
| 175 | | stderr = BytesIO() |
| 176 | | management.call_command( |
| 177 | | 'loaddata', |
| 178 | | 'empty', |
| 179 | | verbosity=0, |
| 180 | | commit=False, |
| 181 | | stderr=stderr, |
| 182 | | ) |
| 183 | | self.assertEqual( |
| 184 | | stderr.getvalue(), |
| 185 | | "No fixture data found for 'empty'. (File format may be invalid.)\n" |
| 186 | | ) |
| | 164 | with self.assertRaisesRegexp(management.CommandError, |
| | 165 | "No fixture data found for 'empty'. \(File format may be invalid.\)"): |
| | 166 | management.call_command( |
| | 167 | 'loaddata', |
| | 168 | 'empty', |
| | 169 | verbosity=0, |
| | 170 | commit=False, |
| | 171 | ) |
| 187 | 172 | |
| 188 | 173 | def test_error_message(self): |
| 189 | 174 | """ |
| 190 | 175 | (Regression for #9011 - error message is correct) |
| 191 | 176 | """ |
| 192 | | stderr = BytesIO() |
| 193 | | management.call_command( |
| 194 | | 'loaddata', |
| 195 | | 'bad_fixture2', |
| 196 | | 'animal', |
| 197 | | verbosity=0, |
| 198 | | commit=False, |
| 199 | | stderr=stderr, |
| 200 | | ) |
| 201 | | self.assertEqual( |
| 202 | | stderr.getvalue(), |
| 203 | | "No fixture data found for 'bad_fixture2'. (File format may be invalid.)\n" |
| 204 | | ) |
| | 177 | with self.assertRaisesRegexp(management.CommandError, |
| | 178 | "^No fixture data found for 'bad_fixture2'. \(File format may be invalid.\)$"): |
| | 179 | management.call_command( |
| | 180 | 'loaddata', |
| | 181 | 'bad_fixture2', |
| | 182 | 'animal', |
| | 183 | verbosity=0, |
| | 184 | commit=False, |
| | 185 | ) |
| 205 | 186 | |
| 206 | 187 | def test_pg_sequence_resetting_checks(self): |
| 207 | 188 | """ |
| … |
… |
class TestFixtures(TestCase):
|
| 357 | 338 | """ |
| 358 | 339 | Regression for #3615 - Ensure data with nonexistent child key references raises error |
| 359 | 340 | """ |
| 360 | | stderr = BytesIO() |
| 361 | | management.call_command( |
| 362 | | 'loaddata', |
| 363 | | 'forward_ref_bad_data.json', |
| 364 | | verbosity=0, |
| 365 | | commit=False, |
| 366 | | stderr=stderr, |
| 367 | | ) |
| 368 | | self.assertTrue( |
| 369 | | stderr.getvalue().startswith('Problem installing fixture') |
| 370 | | ) |
| | 341 | with self.assertRaisesRegexp(IntegrityError, |
| | 342 | "Problem installing fixture"): |
| | 343 | management.call_command( |
| | 344 | 'loaddata', |
| | 345 | 'forward_ref_bad_data.json', |
| | 346 | verbosity=0, |
| | 347 | commit=False, |
| | 348 | ) |
| 371 | 349 | |
| 372 | 350 | _cur_dir = os.path.dirname(os.path.abspath(__file__)) |
| 373 | 351 | |
| … |
… |
class TestFixtures(TestCase):
|
| 392 | 370 | """ |
| 393 | 371 | Regression for #7043 - Error is quickly reported when no fixtures is provided in the command line. |
| 394 | 372 | """ |
| 395 | | stderr = BytesIO() |
| 396 | | management.call_command( |
| 397 | | 'loaddata', |
| 398 | | verbosity=0, |
| 399 | | commit=False, |
| 400 | | stderr=stderr, |
| 401 | | ) |
| 402 | | self.assertEqual( |
| 403 | | stderr.getvalue(), 'No database fixture specified. Please provide the path of at least one fixture in the command line.\n' |
| 404 | | ) |
| | 373 | with self.assertRaisesRegexp(management.CommandError, |
| | 374 | "No database fixture specified. Please provide the path of " |
| | 375 | "at least one fixture in the command line."): |
| | 376 | management.call_command( |
| | 377 | 'loaddata', |
| | 378 | verbosity=0, |
| | 379 | commit=False, |
| | 380 | ) |
| 405 | 381 | |
| 406 | 382 | def test_loaddata_not_existant_fixture_file(self): |
| 407 | 383 | stdout_output = BytesIO() |