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() |