def test_fixture_module_string_5(self):
     old_pkgs = getattr(settings, 'FIXTURE_PACKAGES', [])
     settings.FIXTURE_PACKAGES = [
         "class_fixtures.tests.some_fixture_modules",
     ]
     try:
         handlers = associate_handlers(['some_fixtures', 'moar_fixtures'])
         some_module = import_module('class_fixtures.tests.fixtures.some_fixtures')
         moar_module = import_module('class_fixtures.tests.some_fixture_modules.moar_fixtures')
         self.assertEqual(handlers, [
             ('some_fixtures', 'django', None, None),
             ('some_fixtures', 'class_fixtures', 'submodule_name', some_module),
             ('moar_fixtures', 'django', None, None),
             ('moar_fixtures', 'class_fixtures', 'submodule_name', moar_module)
         ])
         l = Loaddata()
         l.stdout = sys.stdout
         l.stderr = sys.stderr
         l.handle('some_fixtures', 'moar_fixtures', verbosity=0)
         self.assertEqual(Company.objects.count(), 1)
         self.assertEqual(Employee.objects.count(), 2)
         self.assertEqual(EmployeeHistory.objects.count(), 2)
         self.assertEqual(Band.objects.count(), 1)
         self.assertEqual(Musician.objects.count(), 1)
         self.assertEqual(Membership.objects.count(), 1)
     finally:
         settings.FIXTURE_PACKAGES = old_pkgs
 def test_appname_fixturemodule_string(self):
     handlers = associate_handlers(['tests.some_fixtures'])
     fixture_submodule = import_module('class_fixtures.tests.fixtures.some_fixtures')
     self.assertEqual(handlers, [('tests.some_fixtures', 'class_fixtures', 'submodule_name', fixture_submodule)])
     l = Loaddata()
     l.stdout = sys.stdout
     l.stderr = sys.stderr
     l.handle('tests.some_fixtures', verbosity=0)
     self.assertEqual(Company.objects.count(), 1)
     self.assertEqual(Employee.objects.count(), 2)
     self.assertEqual(EmployeeHistory.objects.count(), 2)
 def test_fixture_module_string_3(self):
     handlers = associate_handlers(['app_level_fixture.json'])
     self.assertEqual(handlers, [('app_level_fixture.json', 'django', None, None)])
     l = Loaddata()
     l.stdout = sys.stdout
     l.stderr = sys.stderr
     l.handle('app_level_fixture.json', verbosity=0)
     self.assertEqual(Band.objects.count(), 2)
     self.assertEqual(MetalBand.objects.count(), 1)
     self.assertEqual(Musician.objects.count(), 2)
     self.assertEqual(Membership.objects.count(), 3)
     self.assertEqual(Roadie.objects.count(), 1)
     self.assertEqual(Company.objects.count(), 1)
     self.assertEqual(Employee.objects.count(), 2)
     self.assertEqual(EmployeeHistory.objects.count(), 2)
 def test_fixture_module(self):
     fixture_module = import_module('class_fixtures.tests.fixtures.other_fixtures')
     handlers = associate_handlers([fixture_module])
     self.assertEqual(handlers, [(fixture_module, 'class_fixtures', 'module', None)])
     l = Loaddata()
     l.stdout = sys.stdout
     l.stderr = sys.stderr
     l.handle(fixture_module, verbosity=0)
     self.assertEqual(Band.objects.count(), 2)
     self.assertEqual(MetalBand.objects.count(), 1)
     self.assertEqual(Musician.objects.count(), 2)
     self.assertEqual(Membership.objects.count(), 2)
     self.assertEqual(Roadie.objects.count(), 3)
     self.assertEqual(Company.objects.count(), 1)
     self.assertEqual(Employee.objects.count(), 2)
     self.assertEqual(EmployeeHistory.objects.count(), 2)
 def test_appname_string(self):
     handlers = associate_handlers(['tests'])
     fixture_package = import_module('class_fixtures.tests.fixtures')
     self.assertEqual(handlers, [('tests', 'class_fixtures', 'app_label', fixture_package)])
     l = Loaddata()
     l.stdout = sys.stdout
     l.stderr = sys.stderr
     l.handle('tests', verbosity=0)
     # fixtures.some_fixtures and fixtures.other_fixtures contents combined
     self.assertEqual(Band.objects.count(), 2)
     self.assertEqual(MetalBand.objects.count(), 1)
     self.assertEqual(Musician.objects.count(), 2)
     self.assertEqual(Roadie.objects.count(), 3)
     self.assertEqual(Membership.objects.count(), 2)
     self.assertEqual(Company.objects.count(), 2)
     self.assertEqual(Employee.objects.count(), 4)
     self.assertEqual(EmployeeHistory.objects.count(), 4)
 def test_fixture_module_string_4(self):
     # Loads tests/testproject/project_fixtures/project_level_fixture.json
     old_fixture_dirs = settings.FIXTURE_DIRS
     settings.FIXTURE_DIRS = (os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testproject/project_fixtures'),)
     handlers = associate_handlers(['project_level_fixture'])
     self.assertEqual(handlers, [('project_level_fixture', 'django', None, None)])
     try:
         l = Loaddata()
         l.stdout = sys.stdout
         l.stderr = sys.stderr
         l.handle('project_level_fixture', verbosity=0)
     finally:
         settings.FIXTURE_DIRS = old_fixture_dirs
     self.assertEqual(Band.objects.count(), 2)
     self.assertEqual(MetalBand.objects.count(), 1)
     self.assertEqual(Musician.objects.count(), 2)
     self.assertEqual(Membership.objects.count(), 3)
     self.assertEqual(Roadie.objects.count(), 1)
Example #7
0
    def handle(self, *fixture_labels, **options):
        using = options.get('database', DEFAULT_DB_ALIAS)
        connection = connections[using]
        self.style = no_style()
        show_traceback = options.get('traceback', False)
        commit = options.get('commit', True)

        # I'm sure there is a valid reason why Django's loaddata does this,
        # so I'm just going to replicate its behaviour.
        cursor = connection.cursor()

        if commit:
            transaction.commit_unless_managed(using=using)
            transaction.enter_transaction_management(using=using)
            transaction.managed(True, using=using)

        total_object_count = 0
        total_fixture_count = 0
        do_initial_data = False
        captured_outputs = []
        original_verbosity = int(options.get('verbosity'))
        # Mark this loaddata run as a special case for syncdb loading.
        # Django's loaddata will be run first, ours second.
        if fixture_labels == ('initial_data',):
            # Assign a special handler type for initial data
            fixture_handlers = [('initial_data', 'both_for_initial', None, None)]
        else:
            # Build a list of (label, handler, type, resolved_object) tuples.
            fixture_handlers = associate_handlers(fixture_labels)

        for label, handler, type_, obj in fixture_handlers:
            if handler in ['django', 'both_for_initial']:
                captured_stdout = StringIO()
                # Need to assign manually; normally available to handle() via
                # BaseCommand.execute(), but not when we're using it this way.
                DjangoLoaddata.stdout = captured_stdout
                DjangoLoaddata.stderr = self.stderr
                # Capturing fixture counts from stdout requires forcing the
                # verbosity option to a minimum of 1. If set higher by the
                # user, respect that. Collect any extra messages for display.
                if 'verbosity' in options:
                    options['verbosity'] = 1 if options['verbosity'] == 0 else options['verbosity']
                else:
                    options['verbosity'] = 1
                # We will either be in our own transaction handling or that of
                # the script that called us, so disable transaction management
                # inside Django's loaddata
                options['commit'] = False
                try:
                    if 'database' not in options:
                        options.update({'database': using})
                    DjangoLoaddata.handle(label, **options)
                except Exception:
                    if commit:
                        transaction.rollback(using=using)
                        transaction.leave_transaction_management(using=using)
                    raise
                django_object_count, django_fixture_count, other_msgs = process_django_output(captured_stdout.getvalue())
                captured_stdout.close()
                total_object_count += django_object_count
                total_fixture_count += django_fixture_count
                captured_outputs.extend(other_msgs)

            if handler in ['class_fixtures', 'both_for_initial']:
                if type_ == 'instance':
                    fixtures = [label]
                elif type_ == 'module':
                    fixtures = get_fixtures_from_module(label)
                elif type_ == 'submodule_name':
                    # obj is a reference to an individual submodule of
                    # the fixtures package of some app.
                    fixtures = get_fixtures_from_module(obj)
                elif type_ == 'app_label':
                    # obj is a reference to the fixtures package of the
                    # app named in the label. Load all the fixture modules
                    # contained within, excluding initial_data.
                    fixtures = []
                    for importer, module_name, is_pkg in walk_packages(obj.__path__):
                        if module_name == 'initial_data':
                            continue
                        submodule = importer.find_module(module_name).load_module(module_name)
                        submod_fixtures = get_fixtures_from_module(submodule)
                        for submod_fixture in submod_fixtures:
                            # In case the user has a deeper submodule hierarchy in place
                            # with fixtures imported from submodule to submodule, make sure no fixture
                            # is included in the list twice through submodule discovery.
                            if submod_fixture not in fixtures:
                                fixtures.append(submod_fixture)
                elif type_ is None and label == 'initial_data':
                    fixtures = gather_initial_data_fixtures()

                try:
                    saved_set = set()
                    for fixture in fixtures:
                        saved_objects = fixture.load(using=using)
                        for obj in saved_objects.items():
                            saved_set.add(obj)
                        total_fixture_count += 1
                    total_object_count += len(saved_set)
                except (SystemExit, KeyboardInterrupt):
                    raise
                except Exception:
                    import traceback
                    if commit:
                        transaction.rollback(using=using)
                        transaction.leave_transaction_management(using=using)
                    if show_traceback:
                        traceback.print_exc()
                    else:
                        self.stderr.write(
                            self.style.ERROR("Problem installing class-based fixtures: %s" %
                            ''.join(traceback.format_exception(sys.exc_type,
                                 sys.exc_value, sys.exc_traceback))))
                    return
        if commit:
            transaction.commit(using=using)
            transaction.leave_transaction_management(using=using)

        # Same MySQL workaround as in Django's loaddata
        if commit:
            connection.close()

        if total_fixture_count == 0:
            if original_verbosity >= 1:
                self.stdout.write("No fixtures found.\n")
        else:
            if original_verbosity >= 2 and captured_outputs:
                # Prevent printing Django's result row along with our own
                # when both handlers activate but only class-based fixtures
                # are found.
                if captured_outputs[-1].startswith('No fixtures found.'):
                    captured_outputs = captured_outputs[:-1]
                self.stdout.write('\n'.join(captured_outputs) + '\n')
            if original_verbosity >= 1:
                # The original loaddata has another possible output format
                # used when less objects were loaded than were present in the
                # fixtures, but I don't care enough to implement it.
                self.stdout.write("Installed %d object(s) from %d fixture(s)\n" %
                    (total_object_count, total_fixture_count))
 def test_fixture_instance(self):
     band_fixture = Fixture(Band)
     handlers = associate_handlers([band_fixture])
     self.assertEqual(handlers, [(band_fixture, 'class_fixtures', 'instance', None)])