app/django/core/management/commands/loaddata.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     8     set
     8     set
     9 except NameError:
     9 except NameError:
    10     from sets import Set as set   # Python 2.3 fallback
    10     from sets import Set as set   # Python 2.3 fallback
    11 
    11 
    12 class Command(BaseCommand):
    12 class Command(BaseCommand):
    13     option_list = BaseCommand.option_list + (
       
    14         make_option('--verbosity', action='store', dest='verbosity', default='1',
       
    15             type='choice', choices=['0', '1', '2'],
       
    16             help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
       
    17     )
       
    18     help = 'Installs the named fixture(s) in the database.'
    13     help = 'Installs the named fixture(s) in the database.'
    19     args = "fixture [fixture ...]"
    14     args = "fixture [fixture ...]"
    20 
    15 
    21     def handle(self, *fixture_labels, **options):
    16     def handle(self, *fixture_labels, **options):
    22         from django.db.models import get_apps
    17         from django.db.models import get_apps
    27         self.style = no_style()
    22         self.style = no_style()
    28 
    23 
    29         verbosity = int(options.get('verbosity', 1))
    24         verbosity = int(options.get('verbosity', 1))
    30         show_traceback = options.get('traceback', False)
    25         show_traceback = options.get('traceback', False)
    31 
    26 
       
    27         # commit is a stealth option - it isn't really useful as
       
    28         # a command line option, but it can be useful when invoking
       
    29         # loaddata from within another script.
       
    30         # If commit=True, loaddata will use its own transaction;
       
    31         # if commit=False, the data load SQL will become part of
       
    32         # the transaction in place when loaddata was invoked.
       
    33         commit = options.get('commit', True)
       
    34 
    32         # Keep a count of the installed objects and fixtures
    35         # Keep a count of the installed objects and fixtures
    33         fixture_count = 0
    36         fixture_count = 0
    34         object_count = 0
    37         object_count = 0
       
    38         objects_per_fixture = []
    35         models = set()
    39         models = set()
    36 
    40 
    37         humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
    41         humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
    38 
    42 
    39         # Get a cursor (even though we don't need one yet). This has
    43         # Get a cursor (even though we don't need one yet). This has
    41         # it isn't already initialized).
    45         # it isn't already initialized).
    42         cursor = connection.cursor()
    46         cursor = connection.cursor()
    43 
    47 
    44         # Start transaction management. All fixtures are installed in a
    48         # Start transaction management. All fixtures are installed in a
    45         # single transaction to ensure that all references are resolved.
    49         # single transaction to ensure that all references are resolved.
    46         transaction.commit_unless_managed()
    50         if commit:
    47         transaction.enter_transaction_management()
    51             transaction.commit_unless_managed()
    48         transaction.managed(True)
    52             transaction.enter_transaction_management()
       
    53             transaction.managed(True)
    49 
    54 
    50         app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
    55         app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
    51         for fixture_label in fixture_labels:
    56         for fixture_label in fixture_labels:
    52             parts = fixture_label.split('.')
    57             parts = fixture_label.split('.')
    53             if len(parts) == 1:
    58             if len(parts) == 1:
    58                 if format in serializers.get_public_serializer_formats():
    63                 if format in serializers.get_public_serializer_formats():
    59                     formats = [format]
    64                     formats = [format]
    60                 else:
    65                 else:
    61                     formats = []
    66                     formats = []
    62 
    67 
    63             if verbosity >= 2:
    68             if formats:
    64                 if formats:
    69                 if verbosity > 1:
    65                     print "Loading '%s' fixtures..." % fixture_name
    70                     print "Loading '%s' fixtures..." % fixture_name
    66                 else:
    71             else:
    67                     print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format)
    72                 sys.stderr.write(
       
    73                     self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." %
       
    74                         (fixture_name, format)))
       
    75                 transaction.rollback()
       
    76                 transaction.leave_transaction_management()
       
    77                 return
    68 
    78 
    69             if os.path.isabs(fixture_name):
    79             if os.path.isabs(fixture_name):
    70                 fixture_dirs = [fixture_name]
    80                 fixture_dirs = [fixture_name]
    71             else:
    81             else:
    72                 fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + ['']
    82                 fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + ['']
    91                             transaction.rollback()
   101                             transaction.rollback()
    92                             transaction.leave_transaction_management()
   102                             transaction.leave_transaction_management()
    93                             return
   103                             return
    94                         else:
   104                         else:
    95                             fixture_count += 1
   105                             fixture_count += 1
       
   106                             objects_per_fixture.append(0)
    96                             if verbosity > 0:
   107                             if verbosity > 0:
    97                                 print "Installing %s fixture '%s' from %s." % \
   108                                 print "Installing %s fixture '%s' from %s." % \
    98                                     (format, fixture_name, humanize(fixture_dir))
   109                                     (format, fixture_name, humanize(fixture_dir))
    99                             try:
   110                             try:
   100                                 objects = serializers.deserialize(format, fixture)
   111                                 objects = serializers.deserialize(format, fixture)
   101                                 for obj in objects:
   112                                 for obj in objects:
   102                                     object_count += 1
   113                                     object_count += 1
       
   114                                     objects_per_fixture[-1] += 1
   103                                     models.add(obj.object.__class__)
   115                                     models.add(obj.object.__class__)
   104                                     obj.save()
   116                                     obj.save()
   105                                 label_found = True
   117                                 label_found = True
   106                             except Exception, e:
   118                             except (SystemExit, KeyboardInterrupt):
       
   119                                 raise
       
   120                             except Exception:
       
   121                                 import traceback
   107                                 fixture.close()
   122                                 fixture.close()
   108                                 transaction.rollback()
   123                                 transaction.rollback()
   109                                 transaction.leave_transaction_management()
   124                                 transaction.leave_transaction_management()
   110                                 if show_traceback:
   125                                 if show_traceback:
   111                                     import traceback
   126                                     import traceback
   112                                     traceback.print_exc()
   127                                     traceback.print_exc()
   113                                 else:
   128                                 else:
   114                                     sys.stderr.write(
   129                                     sys.stderr.write(
   115                                         self.style.ERROR("Problem installing fixture '%s': %s\n" %
   130                                         self.style.ERROR("Problem installing fixture '%s': %s\n" %
   116                                              (full_path, str(e))))
   131                                              (full_path, traceback.format_exc())))
   117                                 return
   132                                 return
   118                             fixture.close()
   133                             fixture.close()
   119                     except:
   134                     except:
   120                         if verbosity >= 2:
   135                         if verbosity > 1:
   121                             print "No %s fixture '%s' in %s." % \
   136                             print "No %s fixture '%s' in %s." % \
   122                                 (format, fixture_name, humanize(fixture_dir))
   137                                 (format, fixture_name, humanize(fixture_dir))
   123 
   138 
       
   139 
       
   140         # If any of the fixtures we loaded contain 0 objects, assume that an
       
   141         # error was encountered during fixture loading.
       
   142         if 0 in objects_per_fixture:
       
   143             sys.stderr.write(
       
   144                 self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" %
       
   145                     (fixture_name)))
       
   146             transaction.rollback()
       
   147             transaction.leave_transaction_management()
       
   148             return
       
   149 
       
   150         # If we found even one object in a fixture, we need to reset the
       
   151         # database sequences.
   124         if object_count > 0:
   152         if object_count > 0:
   125             sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
   153             sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
   126             if sequence_sql:
   154             if sequence_sql:
   127                 if verbosity > 1:
   155                 if verbosity > 1:
   128                     print "Resetting sequences"
   156                     print "Resetting sequences"
   129                 for line in sequence_sql:
   157                 for line in sequence_sql:
   130                     cursor.execute(line)
   158                     cursor.execute(line)
   131 
   159 
   132         transaction.commit()
   160         if commit:
   133         transaction.leave_transaction_management()
   161             transaction.commit()
       
   162             transaction.leave_transaction_management()
   134 
   163 
   135         if object_count == 0:
   164         if object_count == 0:
   136             if verbosity >= 2:
   165             if verbosity > 1:
   137                 print "No fixtures found."
   166                 print "No fixtures found."
   138         else:
   167         else:
   139             if verbosity > 0:
   168             if verbosity > 0:
   140                 print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
   169                 print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
       
   170 
       
   171         # Close the DB connection. This is required as a workaround for an
       
   172         # edge case in MySQL: if the same connection is used to
       
   173         # create tables, load data, and query, the query can return
       
   174         # incorrect results. See Django #7572, MySQL #37735.
       
   175         if commit:
       
   176             connection.close()