web/lib/django/core/management/commands/loaddata.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     2 import os
     2 import os
     3 import gzip
     3 import gzip
     4 import zipfile
     4 import zipfile
     5 from optparse import make_option
     5 from optparse import make_option
     6 
     6 
       
     7 from django.conf import settings
       
     8 from django.core import serializers
     7 from django.core.management.base import BaseCommand
     9 from django.core.management.base import BaseCommand
     8 from django.core.management.color import no_style
    10 from django.core.management.color import no_style
     9 
    11 from django.db import connections, router, transaction, DEFAULT_DB_ALIAS
    10 try:
    12 from django.db.models import get_apps
    11     set
    13 from django.utils.itercompat import product
    12 except NameError:
       
    13     from sets import Set as set   # Python 2.3 fallback
       
    14 
    14 
    15 try:
    15 try:
    16     import bz2
    16     import bz2
    17     has_bz2 = True
    17     has_bz2 = True
    18 except ImportError:
    18 except ImportError:
    20 
    20 
    21 class Command(BaseCommand):
    21 class Command(BaseCommand):
    22     help = 'Installs the named fixture(s) in the database.'
    22     help = 'Installs the named fixture(s) in the database.'
    23     args = "fixture [fixture ...]"
    23     args = "fixture [fixture ...]"
    24 
    24 
       
    25     option_list = BaseCommand.option_list + (
       
    26         make_option('--database', action='store', dest='database',
       
    27             default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
       
    28                 'fixtures into. Defaults to the "default" database.'),
       
    29     )
       
    30 
    25     def handle(self, *fixture_labels, **options):
    31     def handle(self, *fixture_labels, **options):
    26         from django.db.models import get_apps
    32         using = options.get('database', DEFAULT_DB_ALIAS)
    27         from django.core import serializers
    33 
    28         from django.db import connection, transaction
    34         connection = connections[using]
    29         from django.conf import settings
       
    30 
       
    31         self.style = no_style()
    35         self.style = no_style()
    32 
    36 
    33         verbosity = int(options.get('verbosity', 1))
    37         verbosity = int(options.get('verbosity', 1))
    34         show_traceback = options.get('traceback', False)
    38         show_traceback = options.get('traceback', False)
    35 
    39 
    54         cursor = connection.cursor()
    58         cursor = connection.cursor()
    55 
    59 
    56         # Start transaction management. All fixtures are installed in a
    60         # Start transaction management. All fixtures are installed in a
    57         # single transaction to ensure that all references are resolved.
    61         # single transaction to ensure that all references are resolved.
    58         if commit:
    62         if commit:
    59             transaction.commit_unless_managed()
    63             transaction.commit_unless_managed(using=using)
    60             transaction.enter_transaction_management()
    64             transaction.enter_transaction_management(using=using)
    61             transaction.managed(True)
    65             transaction.managed(True, using=using)
    62 
    66 
    63         class SingleZipReader(zipfile.ZipFile):
    67         class SingleZipReader(zipfile.ZipFile):
    64             def __init__(self, *args, **kwargs):
    68             def __init__(self, *args, **kwargs):
    65                 zipfile.ZipFile.__init__(self, *args, **kwargs)
    69                 zipfile.ZipFile.__init__(self, *args, **kwargs)
    66                 if settings.DEBUG:
    70                 if settings.DEBUG:
    74             'zip':  SingleZipReader
    78             'zip':  SingleZipReader
    75         }
    79         }
    76         if has_bz2:
    80         if has_bz2:
    77             compression_types['bz2'] = bz2.BZ2File
    81             compression_types['bz2'] = bz2.BZ2File
    78 
    82 
    79         app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
    83         app_module_paths = []
       
    84         for app in get_apps():
       
    85             if hasattr(app, '__path__'):
       
    86                 # It's a 'models/' subpackage
       
    87                 for path in app.__path__:
       
    88                     app_module_paths.append(path)
       
    89             else:
       
    90                 # It's a models.py module
       
    91                 app_module_paths.append(app.__file__)
       
    92 
       
    93         app_fixtures = [os.path.join(os.path.dirname(path), 'fixtures') for path in app_module_paths]
    80         for fixture_label in fixture_labels:
    94         for fixture_label in fixture_labels:
    81             parts = fixture_label.split('.')
    95             parts = fixture_label.split('.')
    82 
    96 
    83             if len(parts) > 1 and parts[-1] in compression_types:
    97             if len(parts) > 1 and parts[-1] in compression_types:
    84                 compression_formats = [parts[-1]]
    98                 compression_formats = [parts[-1]]
   101                     print "Loading '%s' fixtures..." % fixture_name
   115                     print "Loading '%s' fixtures..." % fixture_name
   102             else:
   116             else:
   103                 sys.stderr.write(
   117                 sys.stderr.write(
   104                     self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." %
   118                     self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." %
   105                         (fixture_name, format)))
   119                         (fixture_name, format)))
   106                 transaction.rollback()
   120                 transaction.rollback(using=using)
   107                 transaction.leave_transaction_management()
   121                 transaction.leave_transaction_management(using=using)
   108                 return
   122                 return
   109 
   123 
   110             if os.path.isabs(fixture_name):
   124             if os.path.isabs(fixture_name):
   111                 fixture_dirs = [fixture_name]
   125                 fixture_dirs = [fixture_name]
   112             else:
   126             else:
   115             for fixture_dir in fixture_dirs:
   129             for fixture_dir in fixture_dirs:
   116                 if verbosity > 1:
   130                 if verbosity > 1:
   117                     print "Checking %s for fixtures..." % humanize(fixture_dir)
   131                     print "Checking %s for fixtures..." % humanize(fixture_dir)
   118 
   132 
   119                 label_found = False
   133                 label_found = False
   120                 for format in formats:
   134                 for combo in product([using, None], formats, compression_formats):
   121                     for compression_format in compression_formats:
   135                     database, format, compression_format = combo
   122                         if compression_format: 
   136                     file_name = '.'.join(
   123                             file_name = '.'.join([fixture_name, format, 
   137                         p for p in [
   124                                                   compression_format])
   138                             fixture_name, database, format, compression_format
   125                         else: 
   139                         ]
   126                             file_name = '.'.join([fixture_name, format])
   140                         if p
   127                     
   141                     )
   128                         if verbosity > 1:
   142 
   129                             print "Trying %s for %s fixture '%s'..." % \
   143                     if verbosity > 1:
   130                                 (humanize(fixture_dir), file_name, fixture_name)
   144                         print "Trying %s for %s fixture '%s'..." % \
   131                         full_path = os.path.join(fixture_dir, file_name)
   145                             (humanize(fixture_dir), file_name, fixture_name)
   132                         open_method = compression_types[compression_format]                                
   146                     full_path = os.path.join(fixture_dir, file_name)
   133                         try: 
   147                     open_method = compression_types[compression_format]
   134                             fixture = open_method(full_path, 'r')
   148                     try:
   135                             if label_found:
   149                         fixture = open_method(full_path, 'r')
   136                                 fixture.close()
   150                         if label_found:
   137                                 print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %
   151                             fixture.close()
   138                                     (fixture_name, humanize(fixture_dir)))
   152                             print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %
   139                                 transaction.rollback()
   153                                 (fixture_name, humanize(fixture_dir)))
   140                                 transaction.leave_transaction_management()
   154                             transaction.rollback(using=using)
   141                                 return
   155                             transaction.leave_transaction_management(using=using)
   142                             else:
   156                             return
   143                                 fixture_count += 1
   157                         else:
   144                                 objects_in_fixture = 0
   158                             fixture_count += 1
   145                                 if verbosity > 0:
   159                             objects_in_fixture = 0
   146                                     print "Installing %s fixture '%s' from %s." % \
   160                             if verbosity > 0:
   147                                         (format, fixture_name, humanize(fixture_dir))
   161                                 print "Installing %s fixture '%s' from %s." % \
   148                                 try:
   162                                     (format, fixture_name, humanize(fixture_dir))
   149                                     objects = serializers.deserialize(format, fixture)
   163                             try:
   150                                     for obj in objects:
   164                                 objects = serializers.deserialize(format, fixture, using=using)
       
   165                                 for obj in objects:
       
   166                                     if router.allow_syncdb(using, obj.object.__class__):
   151                                         objects_in_fixture += 1
   167                                         objects_in_fixture += 1
   152                                         models.add(obj.object.__class__)
   168                                         models.add(obj.object.__class__)
   153                                         obj.save()
   169                                         obj.save(using=using)
   154                                     object_count += objects_in_fixture
   170                                 object_count += objects_in_fixture
   155                                     label_found = True
   171                                 label_found = True
   156                                 except (SystemExit, KeyboardInterrupt):
   172                             except (SystemExit, KeyboardInterrupt):
   157                                     raise
   173                                 raise
   158                                 except Exception:
   174                             except Exception:
   159                                     import traceback
   175                                 import traceback
   160                                     fixture.close()
       
   161                                     transaction.rollback()
       
   162                                     transaction.leave_transaction_management()
       
   163                                     if show_traceback:
       
   164                                         traceback.print_exc()
       
   165                                     else:
       
   166                                         sys.stderr.write(
       
   167                                             self.style.ERROR("Problem installing fixture '%s': %s\n" %
       
   168                                                  (full_path, ''.join(traceback.format_exception(sys.exc_type, 
       
   169                                                      sys.exc_value, sys.exc_traceback))))) 
       
   170                                     return
       
   171                                 fixture.close()
   176                                 fixture.close()
   172 
   177                                 transaction.rollback(using=using)
   173                                 # If the fixture we loaded contains 0 objects, assume that an
   178                                 transaction.leave_transaction_management(using=using)
   174                                 # error was encountered during fixture loading.
   179                                 if show_traceback:
   175                                 if objects_in_fixture == 0:
   180                                     traceback.print_exc()
       
   181                                 else:
   176                                     sys.stderr.write(
   182                                     sys.stderr.write(
   177                                         self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" %
   183                                         self.style.ERROR("Problem installing fixture '%s': %s\n" %
   178                                             (fixture_name)))
   184                                              (full_path, ''.join(traceback.format_exception(sys.exc_type,
   179                                     transaction.rollback()
   185                                                  sys.exc_value, sys.exc_traceback)))))
   180                                     transaction.leave_transaction_management()
   186                                 return
   181                                     return
   187                             fixture.close()
   182 
   188 
   183                         except Exception, e:
   189                             # If the fixture we loaded contains 0 objects, assume that an
   184                             if verbosity > 1:
   190                             # error was encountered during fixture loading.
   185                                 print "No %s fixture '%s' in %s." % \
   191                             if objects_in_fixture == 0:
   186                                     (format, fixture_name, humanize(fixture_dir))
   192                                 sys.stderr.write(
       
   193                                     self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" %
       
   194                                         (fixture_name)))
       
   195                                 transaction.rollback(using=using)
       
   196                                 transaction.leave_transaction_management(using=using)
       
   197                                 return
       
   198 
       
   199                     except Exception, e:
       
   200                         if verbosity > 1:
       
   201                             print "No %s fixture '%s' in %s." % \
       
   202                                 (format, fixture_name, humanize(fixture_dir))
   187 
   203 
   188         # If we found even one object in a fixture, we need to reset the
   204         # If we found even one object in a fixture, we need to reset the
   189         # database sequences.
   205         # database sequences.
   190         if object_count > 0:
   206         if object_count > 0:
   191             sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
   207             sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
   194                     print "Resetting sequences"
   210                     print "Resetting sequences"
   195                 for line in sequence_sql:
   211                 for line in sequence_sql:
   196                     cursor.execute(line)
   212                     cursor.execute(line)
   197 
   213 
   198         if commit:
   214         if commit:
   199             transaction.commit()
   215             transaction.commit(using=using)
   200             transaction.leave_transaction_management()
   216             transaction.leave_transaction_management(using=using)
   201 
   217 
   202         if object_count == 0:
   218         if object_count == 0:
   203             if verbosity > 1:
   219             if verbosity > 0:
   204                 print "No fixtures found."
   220                 print "No fixtures found."
   205         else:
   221         else:
   206             if verbosity > 0:
   222             if verbosity > 0:
   207                 print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
   223                 print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
   208 
   224