Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #10200 -- Raised CommandError when errors happen in loaddata.

  • Loading branch information...
commit 6fd1950a4e29c1b5ed071a880db64103715ead51 1 parent 4464bbb
Claude Paroz authored June 07, 2012
43  django/core/management/commands/loaddata.py
@@ -7,7 +7,7 @@
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)
@@ -36,11 +36,10 @@ def handle(self, *fixture_labels, **options):
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')
@@ -126,13 +125,9 @@ def read(self):
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]
@@ -167,12 +162,8 @@ def read(self):
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
@@ -191,13 +182,13 @@ def read(self):
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
@@ -208,13 +199,9 @@ def read(self):
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
@@ -223,19 +210,13 @@ def read(self):
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.
25  tests/modeltests/fixtures/tests.py
@@ -4,7 +4,7 @@
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
@@ -232,11 +232,9 @@ def test_compressed_loading(self):
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
@@ -258,10 +256,9 @@ def test_loaddata_error_message(self):
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
@@ -316,11 +313,9 @@ def test_format_discovery(self):
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(), [
142  tests/regressiontests/fixtures_regress/tests.py
@@ -9,7 +9,7 @@
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)
@@ -116,18 +116,15 @@ def test_unknown_format(self):
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
         """
@@ -135,18 +132,14 @@ def test_invalid_data(self):
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
         """
@@ -154,54 +147,42 @@ def test_invalid_data_no_ext(self):
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
         """
@@ -357,17 +338,14 @@ def test_loaddata_raises_error_when_fixture_has_invalid_foreign_key(self):
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
 
@@ -392,16 +370,14 @@ def test_loaddata_no_fixture_specified(self):
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()

0 notes on commit 6fd1950

Please sign in to comment.
Something went wrong with that request. Please try again.