Beispiel #1
0
 def test_apply(self):
     """
     Tests marking migrations as applied/unapplied.
     """
     recorder = MigrationRecorder(connection)
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations() if x == "myapp"),
         set(),
     )
     recorder.record_applied("myapp", "0432_ponies")
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations() if x == "myapp"),
         {("myapp", "0432_ponies")},
     )
     # That should not affect records of another database
     recorder_other = MigrationRecorder(connections['other'])
     self.assertEqual(
         set((x, y) for (x, y) in recorder_other.applied_migrations() if x == "myapp"),
         set(),
     )
     recorder.record_unapplied("myapp", "0432_ponies")
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations() if x == "myapp"),
         set(),
     )
Beispiel #2
0
 def test_apply(self):
     """
     Tests marking migrations as applied/unapplied.
     """
     recorder = MigrationRecorder(connection)
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations()
             if x == "myapp"),
         set(),
     )
     recorder.record_applied("myapp", "0432_ponies")
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations()
             if x == "myapp"),
         {("myapp", "0432_ponies")},
     )
     # That should not affect records of another database
     recorder_other = MigrationRecorder(connections['other'])
     self.assertEqual(
         set((x, y) for (x, y) in recorder_other.applied_migrations()
             if x == "myapp"),
         set(),
     )
     recorder.record_unapplied("myapp", "0432_ponies")
     self.assertEqual(
         set((x, y) for (x, y) in recorder.applied_migrations()
             if x == "myapp"),
         set(),
     )
Beispiel #3
0
 def check_consistent_history(self, connection):
     """
     Raise InconsistentMigrationHistory if any applied migrations have
     unapplied dependencies.
     """
     recorder = MigrationRecorder(connection)
     applied = recorder.applied_migrations()
     for migration in applied:
         # If the migration is unknown, skip it.
         if migration not in self.graph.nodes:
             continue
         for parent in self.graph.node_map[migration].parents:
             if parent not in applied:
                 # Skip unapplied squashed migrations that have all of their
                 # `replaces` applied.
                 if parent in self.replacements:
                     if all(m in applied
                            for m in self.replacements[parent].replaces):
                         continue
                 raise InconsistentMigrationHistory(
                     "Migration {}.{} is applied before its dependency "
                     "{}.{} on database '{}'.".format(
                         migration[0],
                         migration[1],
                         parent[0],
                         parent[1],
                         connection.alias,
                     ))
Beispiel #4
0
 def check_consistent_history(self, connection):
     """
     Raise InconsistentMigrationHistory if any applied migrations have
     unapplied dependencies.
     """
     recorder = MigrationRecorder(connection)
     try:
         applied = recorder.applied_migrations()
     except MigrationSchemaMissing:
         # Skip check if the django_migrations table is missing and can't be
         # created.
         return
     for migration in applied:
         # If the migration is unknown, skip it.
         if migration not in self.graph.nodes:
             continue
         for parent in self.graph.node_map[migration].parents:
             if parent not in applied:
                 # Skip unapplied squashed migrations that have all of their
                 # `replaces` applied.
                 if parent in self.replacements:
                     if all(m in applied for m in self.replacements[parent].replaces):
                         continue
                 raise InconsistentMigrationHistory(
                     "Migration {}.{} is applied before its dependency "
                     "{}.{} on database '{}'.".format(
                         migration[0], migration[1], parent[0], parent[1],
                         connection.alias,
                     )
                 )
Beispiel #5
0
 def build_graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     You'll need to rebuild the graph if you apply migrations. This isn't
     usually a problem as generally migration stuff runs in a one-shot process.
     """
     # Load disk data
     self.load_disk()
     # Load database data
     recorder = MigrationRecorder(self.connection)
     self.applied_migrations = recorder.applied_migrations()
     # Do a first pass to separate out replacing and non-replacing migrations
     normal = {}
     replacing = {}
     for key, migration in self.disk_migrations.items():
         if migration.replaces:
             replacing[key] = migration
         else:
             normal[key] = migration
     # Calculate reverse dependencies - i.e., for each migration, what depends on it?
     # This is just for dependency re-pointing when applying replacements,
     # so we ignore run_before here.
     reverse_dependencies = {}
     for key, migration in normal.items():
         for parent in migration.dependencies:
             reverse_dependencies.setdefault(parent, set()).add(key)
     # Carry out replacements if we can - that is, if all replaced migrations
     # are either unapplied or missing.
     for key, migration in replacing.items():
         # Ensure this replacement migration is not in applied_migrations
         self.applied_migrations.discard(key)
         # Do the check. We can replace if all our replace targets are
         # applied, or if all of them are unapplied.
         applied_statuses = [(target in self.applied_migrations) for target in migration.replaces]
         can_replace = all(applied_statuses) or (not any(applied_statuses))
         if not can_replace:
             continue
         # Alright, time to replace. Step through the replaced migrations
         # and remove, repointing dependencies if needs be.
         for replaced in migration.replaces:
             if replaced in normal:
                 # We don't care if the replaced migration doesn't exist;
                 # the usage pattern here is to delete things after a while.
                 del normal[replaced]
             for child_key in reverse_dependencies.get(replaced, set()):
                 if child_key in migration.replaces:
                     continue
                 normal[child_key].dependencies.remove(replaced)
                 normal[child_key].dependencies.append(key)
         normal[key] = migration
         # Mark the replacement as applied if all its replaced ones are
         if all(applied_statuses):
             self.applied_migrations.add(key)
     # Finally, make a graph and load everything into it
     self.graph = MigrationGraph()
     for key, migration in normal.items():
         self.graph.add_node(key, migration)
     for key, migration in normal.items():
         for parent in migration.dependencies:
             self.graph.add_dependency(key, parent)
Beispiel #6
0
 def check_consistent_history(self, connection):
     """
     Raise InconsistentMigrationHistory if any applied migrations have
     unapplied dependencies.
     """
     recorder = MigrationRecorder(connection)
     try:
         applied = recorder.applied_migrations()
     except MigrationSchemaMissing:
         # Skip check if the django_migrations table is missing and can't be
         # created.
         return
     for migration in applied:
         # If the migration is unknown, skip it.
         if migration not in self.graph.nodes:
             continue
         for parent in self.graph.node_map[migration].parents:
             if parent not in applied:
                 # Skip unapplied squashed migrations that have all of their
                 # `replaces` applied.
                 if parent in self.replacements:
                     if all(m in applied for m in self.replacements[parent].replaces):
                         continue
                 raise InconsistentMigrationHistory(
                     "Migration {}.{} is applied before its dependency {}.{}".format(
                         migration[0], migration[1], parent[0], parent[1],
                     )
                 )
Beispiel #7
0
 def graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     """
     # Make sure we have the disk data
     if self.disk_migrations is None:
         self.load_disk()
     # And the database data
     if self.applied_migrations is None:
         recorder = MigrationRecorder(self.connection)
         self.applied_migrations = recorder.applied_migrations()
     # Do a first pass to separate out replacing and non-replacing migrations
     normal = {}
     replacing = {}
     for key, migration in self.disk_migrations.items():
         if migration.replaces:
             replacing[key] = migration
         else:
             normal[key] = migration
     # Calculate reverse dependencies - i.e., for each migration, what depends on it?
     # This is just for dependency re-pointing when applying replacements,
     # so we ignore run_before here.
     reverse_dependencies = {}
     for key, migration in normal.items():
         for parent in migration.dependencies:
             reverse_dependencies.setdefault(parent, set()).add(key)
     # Carry out replacements if we can - that is, if all replaced migrations
     # are either unapplied or missing.
     for key, migration in replacing.items():
         # Do the check
         can_replace = True
         for target in migration.replaces:
             if target in self.applied_migrations:
                 can_replace = False
                 break
         if not can_replace:
             continue
         # Alright, time to replace. Step through the replaced migrations
         # and remove, repointing dependencies if needs be.
         for replaced in migration.replaces:
             if replaced in normal:
                 # We don't care if the replaced migration doesn't exist;
                 # the usage pattern here is to delete things after a while.
                 del normal[replaced]
             for child_key in reverse_dependencies.get(replaced, set()):
                 normal[child_key].dependencies.remove(replaced)
                 normal[child_key].dependencies.append(key)
         normal[key] = migration
     # Finally, make a graph and load everything into it
     graph = MigrationGraph()
     for key, migration in normal.items():
         graph.add_node(key, migration)
     for key, migration in normal.items():
         for parent in migration.dependencies:
             graph.add_dependency(key, parent)
     return graph
 def test_apply(self):
     """
     Tests marking migrations as applied/unapplied.
     """
     recorder = MigrationRecorder(connection)
     self.assertEqual(
         recorder.applied_migrations(),
         set(),
     )
     recorder.record_applied("myapp", "0432_ponies")
     self.assertEqual(
         recorder.applied_migrations(),
         set([("myapp", "0432_ponies")]),
     )
     recorder.record_unapplied("myapp", "0432_ponies")
     self.assertEqual(
         recorder.applied_migrations(),
         set(),
     )
Beispiel #9
0
 def test_apply(self):
     """
     Tests marking migrations as applied/unapplied.
     """
     recorder = MigrationRecorder(connection)
     self.assertEqual(
         recorder.applied_migrations(),
         set(),
     )
     recorder.record_applied("myapp", "0432_ponies")
     self.assertEqual(
         recorder.applied_migrations(),
         set([("myapp", "0432_ponies")]),
     )
     recorder.record_unapplied("myapp", "0432_ponies")
     self.assertEqual(
         recorder.applied_migrations(),
         set(),
     )
Beispiel #10
0
def func():
    recorder = MigrationRecorder(connections['default'])
    migrations_were_applied = recorder.applied_migrations()
    print("\033[0m" + '#####################', migrations_were_applied)
    if migrations_were_applied:
        session = requests.Session()
        url = 'http://otp.spider.ru/test/companies/'
        r = session.get(url, headers={'Content-Type': 'application/json'})
        r = r.json()
        for d in r:
            i = d['id']
            name = d['name']
            if d.get('description'):
                description = d['description']
            else:
                description = ''

            COMPANY, _ = Company.objects.update_or_create(name=name,
                                                          defaults={
                                                              'name':
                                                              name,
                                                              'description':
                                                              description
                                                          })

            products_url = f'http://otp.spider.ru/test/companies/{i}/products/'
            result = session.get(products_url,
                                 headers={'Content-Type': 'application/json'})
            fetched_data_of_company = result.json()

            for d in fetched_data_of_company:
                category = d.get('category')
                category_name = category.get('name')

                CATEGORY, _ = Category.objects.update_or_create(
                    title=category_name, defaults={'title': category_name})
                product_name = d.get('name')
                description = d.get('description')
                description = '' if description is None else description

                print(
                    Product.objects.update_or_create(title=product_name,
                                                     description=description,
                                                     defaults={
                                                         'title': product_name,
                                                         'description':
                                                         description,
                                                         'category': CATEGORY,
                                                         'company': COMPANY
                                                     }))
    else:
        print(
            "\033[91m" +
            'PLEASE MAKE MIGRATIONS: docker exec -it spider_group_web_1 python manage.py migrate'
        )
Beispiel #11
0
 def graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     """
     # Make sure we have the disk data
     if self.disk_migrations is None:
         self.load_disk()
     # And the database data
     if self.applied_migrations is None:
         recorder = MigrationRecorder(self.connection)
         self.applied_migrations = recorder.applied_migrations()
     # Do a first pass to separate out replacing and non-replacing migrations
     normal = {}
     replacing = {}
     for key, migration in self.disk_migrations.items():
         if migration.replaces:
             replacing[key] = migration
         else:
             normal[key] = migration
     # Calculate reverse dependencies - i.e., for each migration, what depends on it?
     # This is just for dependency re-pointing when applying replacements,
     # so we ignore run_before here.
     reverse_dependencies = {}
     for key, migration in normal.items():
         for parent in migration.dependencies:
             reverse_dependencies.setdefault(parent, set()).add(key)
     # Carry out replacements if we can - that is, if all replaced migrations
     # are either unapplied or missing.
     for key, migration in replacing.items():
         # Do the check
         can_replace = True
         for target in migration.replaces:
             if target in self.applied_migrations:
                 can_replace = False
                 break
         if not can_replace:
             continue
         # Alright, time to replace. Step through the replaced migrations
         # and remove, repointing dependencies if needs be.
         for replaced in migration.replaces:
             if replaced in normal:
                 del normal[replaced]
             for child_key in reverse_dependencies.get(replaced, set()):
                 normal[child_key].dependencies.remove(replaced)
                 normal[child_key].dependencies.append(key)
         normal[key] = migration
     # Finally, make a graph and load everything into it
     graph = MigrationGraph()
     for key, migration in normal.items():
         graph.add_node(key, migration)
     for key, migration in normal.items():
         for parent in migration.dependencies:
             graph.add_dependency(key, parent)
     return graph
Beispiel #12
0
 def test_migrate_record_squashed(self):
     """
     Running migrate for a squashed migration should record as run
     if all of the replaced migrations have been run (#25231).
     """
     recorder = MigrationRecorder(connection)
     recorder.record_applied("migrations", "0001_initial")
     recorder.record_applied("migrations", "0002_second")
     out = six.StringIO()
     call_command("migrate", "migrations", verbosity=0)
     call_command("showmigrations", "migrations", stdout=out, no_color=True)
     self.assertEqual("migrations\n" " [x] 0001_squashed_0002 (2 squashed migrations)\n", out.getvalue().lower())
     self.assertIn(("migrations", "0001_squashed_0002"), recorder.applied_migrations())
Beispiel #13
0
 def show_list(self, connection, app_names=None):
     """
     Show a list of all migrations on the system, or only those of
     some named apps.
     """
     # Load migrations from disk/DB
     loader = MigrationLoader(connection, ignore_no_migrations=True)
     recorder = MigrationRecorder(connection)
     recorded_migrations = recorder.applied_migrations()
     graph = loader.graph
     # If we were passed a list of apps, validate it
     if app_names:
         self._validate_app_names(loader, app_names)
     # Otherwise, show all apps in alphabetic order
     else:
         app_names = sorted(loader.migrated_apps)
     # For each app, print its migrations in order from oldest (roots) to
     # newest (leaves).
     for app_name in app_names:
         self.stdout.write(app_name, self.style.MIGRATE_LABEL)
         shown = set()
         for node in graph.leaf_nodes(app_name):
             for plan_node in graph.forwards_plan(node):
                 if plan_node not in shown and plan_node[0] == app_name:
                     # Give it a nice title if it's a squashed one
                     title = plan_node[1]
                     if graph.nodes[plan_node].replaces:
                         title += " (%s squashed migrations)" % len(
                             graph.nodes[plan_node].replaces)
                     applied_migration = loader.applied_migrations.get(
                         plan_node)
                     # Mark it as applied/unapplied
                     if applied_migration:
                         if plan_node in recorded_migrations:
                             output = " [X] %s" % title
                         else:
                             title += " Run 'manage.py migrate' to finish recording."
                             output = " [-] %s" % title
                         if self.verbosity >= 2 and hasattr(
                                 applied_migration, "applied"):
                             output += (" (applied at %s)" %
                                        applied_migration.applied.strftime(
                                            "%Y-%m-%d %H:%M:%S"))
                         self.stdout.write(output)
                     else:
                         self.stdout.write(" [ ] %s" % title)
                     shown.add(plan_node)
         # If we didn't print anything, then a small message
         if not shown:
             self.stdout.write(" (no migrations)", self.style.ERROR)
Beispiel #14
0
def is_migration_applied(app, name):
    """
    Check on migrations database table if the given migration is applied to the database.

    Args:
    app (string): django app to which the migration belongs.
    name (string): migration name.

    Returns:
    bool: True, if the migration is applied.
    """
    db_connection = connections[DEFAULT_DB_ALIAS]
    recorder = MigrationRecorder(db_connection)
    migrations = recorder.applied_migrations()
    return migrations.intersection({(app, name)})
Beispiel #15
0
 def test_migrate_record_replaced(self):
     """
     Running a single squashed migration should record all of the original
     replaced migrations as run.
     """
     recorder = MigrationRecorder(connection)
     out = six.StringIO()
     call_command("migrate", "migrations", verbosity=0)
     call_command("showmigrations", "migrations", stdout=out, no_color=True)
     self.assertEqual("migrations\n" " [x] 0001_squashed_0002 (2 squashed migrations)\n", out.getvalue().lower())
     applied_migrations = recorder.applied_migrations()
     self.assertIn(("migrations", "0001_initial"), applied_migrations)
     self.assertIn(("migrations", "0002_second"), applied_migrations)
     self.assertIn(("migrations", "0001_squashed_0002"), applied_migrations)
     # Rollback changes
     call_command("migrate", "migrations", "zero", verbosity=0)
    def test_migrate_marks_replacement_applied_even_if_it_did_nothing(self):
        """
        A new squash migration will be marked as applied even if all its
        replaced migrations were previously already applied (#24628).
        """
        recorder = MigrationRecorder(connection)
        # Record all replaced migrations as applied
        recorder.record_applied("migrations", "0001_initial")
        recorder.record_applied("migrations", "0002_second")
        executor = MigrationExecutor(connection)
        executor.migrate([("migrations", "0001_squashed_0002")])

        # Because 0001 and 0002 are both applied, even though this migrate run
        # didn't apply anything new, their squashed replacement should be
        # marked as applied.
        self.assertIn(("migrations", "0001_squashed_0002"), recorder.applied_migrations())
Beispiel #17
0
 def test_migrate_record_squashed(self):
     """
     Running migrate for a squashed migration should record as run
     if all of the replaced migrations have been run (#25231).
     """
     recorder = MigrationRecorder(connection)
     recorder.record_applied("migrations", "0001_initial")
     recorder.record_applied("migrations", "0002_second")
     out = six.StringIO()
     call_command("migrate", "migrations", verbosity=0)
     call_command("showmigrations", "migrations", stdout=out, no_color=True)
     self.assertEqual(
         'migrations\n'
         ' [x] 0001_squashed_0002 (2 squashed migrations)\n',
         out.getvalue().lower())
     self.assertIn(("migrations", "0001_squashed_0002"),
                   recorder.applied_migrations())
Beispiel #18
0
 def check_consistent_history(self, connection):
     """
     Raise InconsistentMigrationHistory if any applied migrations have
     unapplied dependencies.
     """
     recorder = MigrationRecorder(connection)
     applied = recorder.applied_migrations()
     for migration in applied:
         # If the migration is unknown, skip it.
         if migration not in self.graph.nodes:
             continue
         for parent in self.graph.node_map[migration].parents:
             if parent not in applied:
                 raise InconsistentMigrationHistory(
                     "Migration {}.{} is applied before its dependency {}.{}".format(
                         migration[0], migration[1], parent[0], parent[1],
                     )
                 )
Beispiel #19
0
 def check_consistent_history(self, connection):
     """
     Raise InconsistentMigrationHistory if any applied migrations have
     unapplied dependencies.
     """
     recorder = MigrationRecorder(connection)
     applied = recorder.applied_migrations()
     for migration in applied:
         # If the migration is unknown, skip it.
         if migration not in self.graph.nodes:
             continue
         for parent in self.graph.node_map[migration].parents:
             if parent not in applied:
                 raise InconsistentMigrationHistory(
                     "Migration {}.{} is applied before its dependency {}.{}".format(
                         migration[0], migration[1], parent[0], parent[1],
                     )
                 )
    def test_apply_all_replaced_marks_replacement_as_applied(self):
        """
        Applying all replaced migrations marks replacement as applied (#24628).
        """
        recorder = MigrationRecorder(connection)
        # Place the database in a state where the replaced migrations are
        # partially applied: 0001 is applied, 0002 is not.
        recorder.record_applied("migrations", "0001_initial")
        executor = MigrationExecutor(connection)
        # Use fake because we don't actually have the first migration
        # applied, so the second will fail. And there's no need to actually
        # create/modify tables here, we're just testing the
        # MigrationRecord, which works the same with or without fake.
        executor.migrate([("migrations", "0002_second")], fake=True)

        # Because we've now applied 0001 and 0002 both, their squashed
        # replacement should be marked as applied.
        self.assertIn(("migrations", "0001_squashed_0002"), recorder.applied_migrations())
    def test_migrate_marks_replacement_applied_even_if_it_did_nothing(self):
        """
        A new squash migration will be marked as applied even if all its
        replaced migrations were previously already applied (#24628).
        """
        recorder = MigrationRecorder(connection)
        # Record all replaced migrations as applied
        recorder.record_applied("migrations", "0001_initial")
        recorder.record_applied("migrations", "0002_second")
        executor = MigrationExecutor(connection)
        executor.migrate([("migrations", "0001_squashed_0002")])

        # Because 0001 and 0002 are both applied, even though this migrate run
        # didn't apply anything new, their squashed replacement should be
        # marked as applied.
        self.assertIn(
            ("migrations", "0001_squashed_0002"),
            recorder.applied_migrations(),
        )
Beispiel #22
0
def app_has_unapplied_migrations(app_name):
    # Note: We cannot configure Django globally, because some config files
    # might not exist yet.
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "initat.cluster.settings")

    connection, apps, MigrationRecorder = setup_django()

    recorder = MigrationRecorder(connection)
    applied_migrations = {
        migration_name for app_name_, migration_name in recorder.applied_migrations()
        if app_name_ == app_name
    }
    migration_directory = os.path.join(apps.get_app_config(app_name).path, "migrations")
    migrations_on_disk = set(
        fnmatch.filter(os.listdir(migration_directory), "*.py")
    )
    migrations_on_disk = {os.path.splitext(i)[0] for i in migrations_on_disk}
    migrations_on_disk.remove("__init__")
    return len(migrations_on_disk - applied_migrations) > 0
Beispiel #23
0
 def test_migrate_record_replaced(self):
     """
     Running a single squashed migration should record all of the original
     replaced migrations as run.
     """
     recorder = MigrationRecorder(connection)
     out = six.StringIO()
     call_command("migrate", "migrations", verbosity=0)
     call_command("showmigrations", "migrations", stdout=out, no_color=True)
     self.assertEqual(
         'migrations\n'
         ' [x] 0001_squashed_0002 (2 squashed migrations)\n',
         out.getvalue().lower())
     applied_migrations = recorder.applied_migrations()
     self.assertIn(("migrations", "0001_initial"), applied_migrations)
     self.assertIn(("migrations", "0002_second"), applied_migrations)
     self.assertIn(("migrations", "0001_squashed_0002"), applied_migrations)
     # Rollback changes
     call_command("migrate", "migrations", "zero", verbosity=0)
Beispiel #24
0
    def check_consistent_migration_file(self, connection):
        """
        Raise InconsistentMigrationFileHistory if a migration file is deleted.
        """
        recorder = MigrationRecorder(connection)
        applied = recorder.applied_migrations()
        # If the migration is unknown, record that as removed file
        deleted_migrations = {}
        for migration in applied:
            if migration not in self.graph.nodes:
                deleted_migrations.setdefault(migration[0], []).append(migration[1])
        error_messages = []

        for app_label in deleted_migrations:
            error_messages.append("   App '%s':\n" % app_label)
            for file_name in deleted_migrations[app_label]:
                error_messages.append("   \t'%s'\n" % file_name)
        if error_messages:
            raise InconsistentMigrationFileHistory(
                "WARNING: Inconsistent migrations\n%s" % "".join(error_messages))
    def test_apply_all_replaced_marks_replacement_as_applied(self):
        """
        Applying all replaced migrations marks replacement as applied (#24628).
        """
        recorder = MigrationRecorder(connection)
        # Place the database in a state where the replaced migrations are
        # partially applied: 0001 is applied, 0002 is not.
        recorder.record_applied("migrations", "0001_initial")
        executor = MigrationExecutor(connection)
        # Use fake because we don't actually have the first migration
        # applied, so the second will fail. And there's no need to actually
        # create/modify tables here, we're just testing the
        # MigrationRecord, which works the same with or without fake.
        executor.migrate([("migrations", "0002_second")], fake=True)

        # Because we've now applied 0001 and 0002 both, their squashed
        # replacement should be marked as applied.
        self.assertIn(
            ("migrations", "0001_squashed_0002"),
            recorder.applied_migrations(),
        )
Beispiel #26
0
    def handle(self, *args, **options):
        # check if auth is not finish migrations
        db = options['database']
        connection = connections[db]

        recorder = MigrationRecorder(connection)
        applied = recorder.applied_migrations()

        if applied:
            is_auth_finish = False
            target_init_path = os.path.join(settings.BASE_DIR, 'blueapps',
                                            'account', 'migrations',
                                            '__init__.py')
            target_init_pyc_path = os.path.join(settings.BASE_DIR, 'blueapps',
                                                'account', 'migrations',
                                                '__init__.pyc')

            for migration in applied:

                if migration[0] == 'auth' and migration[1].startswith('0007'):
                    is_auth_finish = True

            if settings.RUN_VER == 'open' and not is_auth_finish:
                sys.stdout.write('remove init for auth is not finish.\n')
                try:
                    os.remove(target_init_path)
                    os.remove(target_init_pyc_path)
                except FileNotFoundError:
                    pass

                sys.stdout.write('ready to execute the true migrate\n')
                super(Command, self).handle(*args, **options)

                if not is_auth_finish:
                    open(target_init_path, 'w')
                    sys.stdout.write(
                        'ready to execute the true migrate again\n')

        super(Command, self).handle(*args, **options)
Beispiel #27
0
    def test_record_applied_migrations(self):
        """Testing record_applied_migrations"""
        connection = connections[DEFAULT_DB_ALIAS]

        # Ideally we'd do an assertNumQueries(2), but MigrationRecorder doesn't
        # cache state and performs repeated queries for the same list of
        # installed table names, followed by new transactions. That might
        # differ depending on the type of database being used.
        migrations = MigrationList()
        migrations.add_migration_info(app_label='tests',
                                      name='0001_initial')
        migrations.add_migration_info(app_label='tests',
                                      name='0002_stuff')

        record_applied_migrations(connection=connection,
                                  migrations=migrations)

        recorder = MigrationRecorder(connection)
        applied_migrations = recorder.applied_migrations()

        self.assertIn(('tests', '0001_initial'), applied_migrations)
        self.assertIn(('tests', '0002_stuff'), applied_migrations)
Beispiel #28
0
    def test_unrecord_applied_migrations(self):
        """Testing unrecord_applied_migrations"""
        connection = connections[DEFAULT_DB_ALIAS]

        migrations = MigrationList()
        migrations.add_migration_info(app_label='tests',
                                      name='0001_initial')
        migrations.add_migration_info(app_label='tests',
                                      name='0002_stuff')

        record_applied_migrations(connection=connection,
                                  migrations=migrations)

        unrecord_applied_migrations(connection=connection,
                                    app_label='tests',
                                    migration_names=['0001_initial',
                                                     '0002_stuff'])

        recorder = MigrationRecorder(connection)
        applied_migrations = recorder.applied_migrations()

        self.assertNotIn(('tests', '0001_initial'), applied_migrations)
        self.assertNotIn(('tests', '0002_stuff'), applied_migrations)
Beispiel #29
0
 def build_graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     You'll need to rebuild the graph if you apply migrations. This isn't
     usually a problem as generally migration stuff runs in a one-shot process.
     """
     # Load disk data
     self.load_disk()
     # Load database data
     recorder = MigrationRecorder(self.connection)
     self.applied_migrations = recorder.applied_migrations()
     # Do a first pass to separate out replacing and non-replacing migrations
     normal = {}
     replacing = {}
     for key, migration in self.disk_migrations.items():
         if migration.replaces:
             replacing[key] = migration
         else:
             normal[key] = migration
     # Calculate reverse dependencies - i.e., for each migration, what depends on it?
     # This is just for dependency re-pointing when applying replacements,
     # so we ignore run_before here.
     reverse_dependencies = {}
     for key, migration in normal.items():
         for parent in migration.dependencies:
             reverse_dependencies.setdefault(parent, set()).add(key)
     # Carry out replacements if we can - that is, if all replaced migrations
     # are either unapplied or missing.
     for key, migration in replacing.items():
         # Ensure this replacement migration is not in applied_migrations
         self.applied_migrations.discard(key)
         # Do the check. We can replace if all our replace targets are
         # applied, or if all of them are unapplied.
         applied_statuses = [(target in self.applied_migrations)
                             for target in migration.replaces]
         can_replace = all(applied_statuses) or (not any(applied_statuses))
         if not can_replace:
             continue
         # Alright, time to replace. Step through the replaced migrations
         # and remove, repointing dependencies if needs be.
         for replaced in migration.replaces:
             if replaced in normal:
                 # We don't care if the replaced migration doesn't exist;
                 # the usage pattern here is to delete things after a while.
                 del normal[replaced]
             for child_key in reverse_dependencies.get(replaced, set()):
                 if child_key in migration.replaces:
                     continue
                 normal[child_key].dependencies.remove(replaced)
                 normal[child_key].dependencies.append(key)
         normal[key] = migration
         # Mark the replacement as applied if all its replaced ones are
         if all(applied_statuses):
             self.applied_migrations.add(key)
     # Finally, make a graph and load everything into it
     self.graph = MigrationGraph()
     for key, migration in normal.items():
         self.graph.add_node(key, migration)
     for key, migration in normal.items():
         for parent in migration.dependencies:
             # Special-case __first__, which means "the first migration" for
             # migrated apps, and is ignored for unmigrated apps. It allows
             # makemigrations to declare dependencies on apps before they
             # even have migrations.
             if parent[1] == "__first__" and parent not in self.graph:
                 if parent[0] in self.unmigrated_apps:
                     # This app isn't migrated, but something depends on it.
                     # We'll add a fake initial migration for it into the
                     # graph.
                     app_config = apps.get_app_config(parent[0])
                     ops = []
                     for model in app_config.get_models():
                         model_state = ModelState.from_model(model)
                         ops.append(
                             operations.CreateModel(
                                 name=model_state.name,
                                 fields=model_state.fields,
                                 options=model_state.options,
                                 bases=model_state.bases,
                             ))
                     new_migration = type(
                         "FakeInitialMigration",
                         (Migration, ),
                         {"operations": ops},
                     )(parent[1], parent[0])
                     self.graph.add_node(parent, new_migration)
                     self.applied_migrations.add(parent)
                 elif parent[0] in self.migrated_apps:
                     parent = (parent[0],
                               list(self.graph.root_nodes(parent[0]))[0])
                 else:
                     raise ValueError("Dependency on unknown app %s" %
                                      parent[0])
             self.graph.add_dependency(key, parent)
Beispiel #30
0
from __future__ import unicode_literals
Beispiel #31
0
    def build_graph(self):
        """
        Builds a migration dependency graph using both the disk and database.
        You'll need to rebuild the graph if you apply migrations. This isn't
        usually a problem as generally migration stuff runs in a one-shot process.
        """
        # Load disk data
        self.load_disk()
        # Load database data
        if self.connection is None:
            self.applied_migrations = set()
        else:
            recorder = MigrationRecorder(self.connection)
            self.applied_migrations = recorder.applied_migrations()
        # Do a first pass to separate out replacing and non-replacing migrations
        normal = {}
        replacing = {}
        for key, migration in self.disk_migrations.items():
            if migration.replaces:
                replacing[key] = migration
            else:
                normal[key] = migration
        # Calculate reverse dependencies - i.e., for each migration, what depends on it?
        # This is just for dependency re-pointing when applying replacements,
        # so we ignore run_before here.
        reverse_dependencies = {}
        for key, migration in normal.items():
            for parent in migration.dependencies:
                reverse_dependencies.setdefault(parent, set()).add(key)
        # Remember the possible replacements to generate more meaningful error
        # messages
        reverse_replacements = {}
        for key, migration in replacing.items():
            for replaced in migration.replaces:
                reverse_replacements.setdefault(replaced, set()).add(key)
        # Carry out replacements if we can - that is, if all replaced migrations
        # are either unapplied or missing.
        for key, migration in replacing.items():
            # Ensure this replacement migration is not in applied_migrations
            self.applied_migrations.discard(key)
            # Do the check. We can replace if all our replace targets are
            # applied, or if all of them are unapplied.
            applied_statuses = [(target in self.applied_migrations)
                                for target in migration.replaces]
            can_replace = all(applied_statuses) or (not any(applied_statuses))
            if not can_replace:
                continue
            # Alright, time to replace. Step through the replaced migrations
            # and remove, repointing dependencies if needs be.
            for replaced in migration.replaces:
                if replaced in normal:
                    # We don't care if the replaced migration doesn't exist;
                    # the usage pattern here is to delete things after a while.
                    del normal[replaced]
                for child_key in reverse_dependencies.get(replaced, set()):
                    if child_key in migration.replaces:
                        continue
                    # List of migrations whose dependency on `replaced` needs
                    # to be updated to a dependency on `key`.
                    to_update = []
                    # Child key may itself be replaced, in which case it might
                    # not be in `normal` anymore (depending on whether we've
                    # processed its replacement yet). If it's present, we go
                    # ahead and update it; it may be deleted later on if it is
                    # replaced, but there's no harm in updating it regardless.
                    if child_key in normal:
                        to_update.append(normal[child_key])
                    # If the child key is replaced, we update its replacement's
                    # dependencies too, if necessary. (We don't know if this
                    # replacement will actually take effect or not, but either
                    # way it's OK to update the replacing migration).
                    if child_key in reverse_replacements:
                        for replaces_child_key in reverse_replacements[
                                child_key]:
                            if replaced in replacing[
                                    replaces_child_key].dependencies:
                                to_update.append(replacing[replaces_child_key])
                    # Actually perform the dependency update on all migrations
                    # that require it.
                    for migration_needing_update in to_update:
                        migration_needing_update.dependencies.remove(replaced)
                        migration_needing_update.dependencies.append(key)
            normal[key] = migration
            # Mark the replacement as applied if all its replaced ones are
            if all(applied_statuses):
                self.applied_migrations.add(key)
        # Store the replacement migrations for later checks
        self.replacements = replacing
        # Finally, make a graph and load everything into it
        self.graph = MigrationGraph()
        for key, migration in normal.items():
            self.graph.add_node(key, migration)

        def _reraise_missing_dependency(migration, missing, exc):
            """
            Checks if ``missing`` could have been replaced by any squash
            migration but wasn't because the the squash migration was partially
            applied before. In that case raise a more understandable exception.

            #23556
            """
            if missing in reverse_replacements:
                candidates = reverse_replacements.get(missing, set())
                is_replaced = any(candidate in self.graph.nodes
                                  for candidate in candidates)
                if not is_replaced:
                    tries = ', '.join('%s.%s' % c for c in candidates)
                    exc_value = NodeNotFoundError(
                        "Migration {0} depends on nonexistent node ('{1}', '{2}'). "
                        "Django tried to replace migration {1}.{2} with any of [{3}] "
                        "but wasn't able to because some of the replaced migrations "
                        "are already applied.".format(migration, missing[0],
                                                      missing[1], tries),
                        missing)
                    exc_value.__cause__ = exc
                    six.reraise(NodeNotFoundError, exc_value,
                                sys.exc_info()[2])
            raise exc

        # Add all internal dependencies first to ensure __first__ dependencies
        # find the correct root node.
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] != key[0] or parent[1] == '__first__':
                    # Ignore __first__ references to the same app (#22325)
                    continue
                try:
                    self.graph.add_dependency(migration, key, parent)
                except NodeNotFoundError as e:
                    # Since we added "key" to the nodes before this implies
                    # "parent" is not in there. To make the raised exception
                    # more understandable we check if parent could have been
                    # replaced but hasn't (eg partially applied squashed
                    # migration)
                    _reraise_missing_dependency(migration, parent, e)
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] == key[0]:
                    # Internal dependencies already added.
                    continue
                parent = self.check_key(parent, key[0])
                if parent is not None:
                    try:
                        self.graph.add_dependency(migration, key, parent)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "parent" is not in there.
                        _reraise_missing_dependency(migration, parent, e)
            for child in migration.run_before:
                child = self.check_key(child, key[0])
                if child is not None:
                    try:
                        self.graph.add_dependency(migration, child, key)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "child" is not in there.
                        _reraise_missing_dependency(migration, child, e)
Beispiel #32
0
class Django19MigrationExecutor(object):
    """
    End-to-end migration execution - loads migrations, and runs them
    up or down to a specified set of targets.

    Backported from Django 1.9.1, containing changes from:

    https://github.com/django/django/commit/5aa55038ca9ac44b440b56d1fc4e79c876e51393
    https://github.com/django/django/commit/a80fb8ae24e77abf20047b9dfe867b4b53a8d648
    """
    def __init__(self, connection, progress_callback=None):
        self.connection = connection
        self.loader = MigrationLoader(self.connection)
        self.recorder = MigrationRecorder(self.connection)
        self.progress_callback = progress_callback

    def migration_plan(self, targets, clean_start=False):
        """
        Given a set of targets, returns a list of (Migration instance, backwards?).
        """
        plan = []
        if clean_start:
            applied = set()
        else:
            applied = set(self.loader.applied_migrations)
        for target in targets:
            # If the target is (app_label, None), that means unmigrate everything
            if target[1] is None:
                for root in self.loader.graph.root_nodes():
                    if root[0] == target[0]:
                        for migration in self.loader.graph.backwards_plan(
                                root):
                            if migration in applied:
                                plan.append(
                                    (self.loader.graph.nodes[migration], True))
                                applied.remove(migration)
            # If the migration is already applied, do backwards mode,
            # otherwise do forwards mode.
            elif target in applied:
                # Don't migrate backwards all the way to the target node (that
                # may roll back dependencies in other apps that don't need to
                # be rolled back); instead roll back through target's immediate
                # child(ren) in the same app, and no further.
                next_in_app = sorted(
                    n for n in self.loader.graph.node_map[target].children
                    if n[0] == target[0])
                for node in next_in_app:
                    for migration in self.loader.graph.backwards_plan(node):
                        if migration in applied:
                            plan.append(
                                (self.loader.graph.nodes[migration], True))
                            applied.remove(migration)
            else:
                for migration in self.loader.graph.forwards_plan(target):
                    if migration not in applied:
                        plan.append(
                            (self.loader.graph.nodes[migration], False))
                        applied.add(migration)
        return plan

    def migrate(self, targets, plan=None, fake=False, fake_initial=False):
        """
        Migrates the database up to the given targets.

        Django first needs to create all project states before a migration is
        (un)applied and in a second step run all the database operations.
        """
        if plan is None:
            plan = self.migration_plan(targets)
        # Create the forwards plan Django would follow on an empty database
        full_plan = self.migration_plan(self.loader.graph.leaf_nodes(),
                                        clean_start=True)

        all_forwards = all(not backwards for mig, backwards in plan)
        all_backwards = all(backwards for mig, backwards in plan)

        if not plan:
            pass  # Nothing to do for an empty plan
        elif all_forwards == all_backwards:
            # This should only happen if there's a mixed plan
            raise InvalidMigrationPlan(
                "Migration plans with both forwards and backwards migrations "
                "are not supported. Please split your migration process into "
                "separate plans of only forwards OR backwards migrations.",
                plan,
            )
        elif all_forwards:
            self._migrate_all_forwards(plan,
                                       full_plan,
                                       fake=fake,
                                       fake_initial=fake_initial)
        else:
            # No need to check for `elif all_backwards` here, as that condition
            # would always evaluate to true.
            self._migrate_all_backwards(plan, full_plan, fake=fake)

        self.check_replacements()

    def _migrate_all_forwards(self, plan, full_plan, fake, fake_initial):
        """
        Take a list of 2-tuples of the form (migration instance, False) and
        apply them in the order they occur in the full_plan.
        """
        migrations_to_run = {m[0] for m in plan}
        state = ProjectState(real_apps=list(self.loader.unmigrated_apps))
        for migration, _ in full_plan:
            if not migrations_to_run:
                # We remove every migration that we applied from this set so
                # that we can bail out once the last migration has been applied
                # and don't always run until the very end of the migration
                # process.
                break
            if migration in migrations_to_run:
                if "apps" not in state.__dict__:
                    if self.progress_callback:
                        self.progress_callback("render_start")
                    state.apps  # Render all -- performance critical
                    if self.progress_callback:
                        self.progress_callback("render_success")
                state = self.apply_migration(state,
                                             migration,
                                             fake=fake,
                                             fake_initial=fake_initial)
                migrations_to_run.remove(migration)
            else:
                migration.mutate_state(state, preserve=False)

    def _migrate_all_backwards(self, plan, full_plan, fake):
        """
        Take a list of 2-tuples of the form (migration instance, True) and
        unapply them in reverse order they occur in the full_plan.

        Since unapplying a migration requires the project state prior to that
        migration, Django will compute the migration states before each of them
        in a first run over the plan and then unapply them in a second run over
        the plan.
        """
        migrations_to_run = {m[0] for m in plan}
        # Holds all migration states prior to the migrations being unapplied
        states = {}
        state = ProjectState(real_apps=list(self.loader.unmigrated_apps))
        if self.progress_callback:
            self.progress_callback("render_start")
        for migration, _ in full_plan:
            if not migrations_to_run:
                # We remove every migration that we applied from this set so
                # that we can bail out once the last migration has been applied
                # and don't always run until the very end of the migration
                # process.
                break
            if migration in migrations_to_run:
                if "apps" not in state.__dict__:
                    state.apps  # Render all -- performance critical
                # The state before this migration
                states[migration] = state
                # The old state keeps as-is, we continue with the new state
                state = migration.mutate_state(state, preserve=True)
                migrations_to_run.remove(migration)
            else:
                migration.mutate_state(state, preserve=False)
        if self.progress_callback:
            self.progress_callback("render_success")

        for migration, _ in plan:
            self.unapply_migration(states[migration], migration, fake=fake)

    def collect_sql(self, plan):
        """
        Takes a migration plan and returns a list of collected SQL
        statements that represent the best-efforts version of that plan.
        """
        statements = []
        state = None
        for migration, backwards in plan:
            with self.connection.schema_editor(
                    collect_sql=True) as schema_editor:
                if state is None:
                    state = self.loader.project_state(
                        (migration.app_label, migration.name), at_end=False)
                if not backwards:
                    state = migration.apply(state,
                                            schema_editor,
                                            collect_sql=True)
                else:
                    state = migration.unapply(state,
                                              schema_editor,
                                              collect_sql=True)
            statements.extend(schema_editor.collected_sql)
        return statements

    def apply_migration(self,
                        state,
                        migration,
                        fake=False,
                        fake_initial=False):
        """
        Runs a migration forwards.
        """
        if self.progress_callback:
            self.progress_callback("apply_start", migration, fake)
        if not fake:
            if fake_initial:
                # Test to see if this is an already-applied initial migration
                applied, state = self.detect_soft_applied(state, migration)
                if applied:
                    fake = True
            if not fake:
                # Alright, do it normally
                with self.connection.schema_editor() as schema_editor:
                    state = migration.apply(state, schema_editor)
        # For replacement migrations, record individual statuses
        if migration.replaces:
            for app_label, name in migration.replaces:
                self.recorder.record_applied(app_label, name)
        else:
            self.recorder.record_applied(migration.app_label, migration.name)
        # Report progress
        if self.progress_callback:
            self.progress_callback("apply_success", migration, fake)
        return state

    def unapply_migration(self, state, migration, fake=False):
        """
        Runs a migration backwards.
        """
        if self.progress_callback:
            self.progress_callback("unapply_start", migration, fake)
        if not fake:
            with self.connection.schema_editor() as schema_editor:
                state = migration.unapply(state, schema_editor)
        # For replacement migrations, record individual statuses
        if migration.replaces:
            for app_label, name in migration.replaces:
                self.recorder.record_unapplied(app_label, name)
        else:
            self.recorder.record_unapplied(migration.app_label, migration.name)
        # Report progress
        if self.progress_callback:
            self.progress_callback("unapply_success", migration, fake)
        return state

    def check_replacements(self):
        """
        Mark replacement migrations applied if their replaced set all are.

        We do this unconditionally on every migrate, rather than just when
        migrations are applied or unapplied, so as to correctly handle the case
        when a new squash migration is pushed to a deployment that already had
        all its replaced migrations applied. In this case no new migration will
        be applied, but we still want to correctly maintain the applied state
        of the squash migration.
        """
        applied = self.recorder.applied_migrations()
        for key, migration in self.loader.replacements.items():
            all_applied = all(m in applied for m in migration.replaces)
            if all_applied and key not in applied:
                self.recorder.record_applied(*key)

    def detect_soft_applied(self, project_state, migration):
        """
        Tests whether a migration has been implicitly applied - that the
        tables or columns it would create exist. This is intended only for use
        on initial migrations (as it only looks for CreateModel and AddField).
        """
        if migration.initial is None:
            # Bail if the migration isn't the first one in its app
            if any(app == migration.app_label
                   for app, name in migration.dependencies):
                return False, project_state
        elif migration.initial is False:
            # Bail if it's NOT an initial migration
            return False, project_state

        if project_state is None:
            after_state = self.loader.project_state(
                (migration.app_label, migration.name), at_end=True)
        else:
            after_state = migration.mutate_state(project_state)
        apps = after_state.apps
        found_create_model_migration = False
        found_add_field_migration = False
        existing_table_names = self.connection.introspection.table_names(
            self.connection.cursor())
        # Make sure all create model and add field operations are done
        for operation in migration.operations:
            if isinstance(operation, migrations.CreateModel):
                model = apps.get_model(migration.app_label, operation.name)
                if model._meta.swapped:
                    # We have to fetch the model to test with from the
                    # main app cache, as it's not a direct dependency.
                    model = global_apps.get_model(model._meta.swapped)
                if model._meta.proxy or not model._meta.managed:
                    continue
                if model._meta.db_table not in existing_table_names:
                    return False, project_state
                found_create_model_migration = True
            elif isinstance(operation, migrations.AddField):
                model = apps.get_model(migration.app_label,
                                       operation.model_name)
                if model._meta.swapped:
                    # We have to fetch the model to test with from the
                    # main app cache, as it's not a direct dependency.
                    model = global_apps.get_model(model._meta.swapped)
                if model._meta.proxy or not model._meta.managed:
                    continue

                table = model._meta.db_table
                field = model._meta.get_field(operation.name)

                # Handle implicit many-to-many tables created by AddField.
                if field.many_to_many:
                    if field.remote_field.through._meta.db_table not in existing_table_names:
                        return False, project_state
                    else:
                        found_add_field_migration = True
                        continue

                column_names = [
                    column.name for column in self.connection.introspection.
                    get_table_description(self.connection.cursor(), table)
                ]
                if field.column not in column_names:
                    return False, project_state
                found_add_field_migration = True
        # If we get this far and we found at least one CreateModel or AddField migration,
        # the migration is considered implicitly applied.
        return (found_create_model_migration
                or found_add_field_migration), after_state
Beispiel #33
0
    def build_graph(self):
        """
        Builds a migration dependency graph using both the disk and database.
        You'll need to rebuild the graph if you apply migrations. This isn't
        usually a problem as generally migration stuff runs in a one-shot process.
        """
        # Load disk data
        self.load_disk()
        # Load database data
        if self.connection is None:
            self.applied_migrations = set()
        else:
            recorder = MigrationRecorder(self.connection)
            self.applied_migrations = recorder.applied_migrations()
        # Do a first pass to separate out replacing and non-replacing migrations
        normal = {}
        replacing = {}
        for key, migration in self.disk_migrations.items():
            if migration.replaces:
                replacing[key] = migration
            else:
                normal[key] = migration
        # Calculate reverse dependencies - i.e., for each migration, what depends on it?
        # This is just for dependency re-pointing when applying replacements,
        # so we ignore run_before here.
        reverse_dependencies = {}
        for key, migration in normal.items():
            for parent in migration.dependencies:
                reverse_dependencies.setdefault(parent, set()).add(key)
        # Remember the possible replacements to generate more meaningful error
        # messages
        reverse_replacements = {}
        for key, migration in replacing.items():
            for replaced in migration.replaces:
                reverse_replacements.setdefault(replaced, set()).add(key)
        # Carry out replacements if we can - that is, if all replaced migrations
        # are either unapplied or missing.
        for key, migration in replacing.items():
            # Ensure this replacement migration is not in applied_migrations
            self.applied_migrations.discard(key)
            # Do the check. We can replace if all our replace targets are
            # applied, or if all of them are unapplied.
            applied_statuses = [(target in self.applied_migrations) for target in migration.replaces]
            can_replace = all(applied_statuses) or (not any(applied_statuses))
            if not can_replace:
                continue
            # Alright, time to replace. Step through the replaced migrations
            # and remove, repointing dependencies if needs be.
            for replaced in migration.replaces:
                if replaced in normal:
                    # We don't care if the replaced migration doesn't exist;
                    # the usage pattern here is to delete things after a while.
                    del normal[replaced]
                for child_key in reverse_dependencies.get(replaced, set()):
                    if child_key in migration.replaces:
                        continue
                    # child_key may appear in a replacement
                    if child_key in reverse_replacements:
                        for replaced_child_key in reverse_replacements[child_key]:
                            if replaced in replacing[replaced_child_key].dependencies:
                                replacing[replaced_child_key].dependencies.remove(replaced)
                                replacing[replaced_child_key].dependencies.append(key)
                    else:
                        normal[child_key].dependencies.remove(replaced)
                        normal[child_key].dependencies.append(key)
            normal[key] = migration
            # Mark the replacement as applied if all its replaced ones are
            if all(applied_statuses):
                self.applied_migrations.add(key)
        # Finally, make a graph and load everything into it
        self.graph = MigrationGraph()
        for key, migration in normal.items():
            self.graph.add_node(key, migration)

        def _reraise_missing_dependency(migration, missing, exc):
            """
            Checks if ``missing`` could have been replaced by any squash
            migration but wasn't because the the squash migration was partially
            applied before. In that case raise a more understandable exception.

            #23556
            """
            if missing in reverse_replacements:
                candidates = reverse_replacements.get(missing, set())
                is_replaced = any(candidate in self.graph.nodes for candidate in candidates)
                if not is_replaced:
                    tries = ', '.join('%s.%s' % c for c in candidates)
                    exc_value = NodeNotFoundError(
                        "Migration {0} depends on nonexistent node ('{1}', '{2}'). "
                        "Django tried to replace migration {1}.{2} with any of [{3}] "
                        "but wasn't able to because some of the replaced migrations "
                        "are already applied.".format(
                            migration, missing[0], missing[1], tries
                        ),
                        missing)
                    exc_value.__cause__ = exc
                    six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2])
            raise exc

        # Add all internal dependencies first to ensure __first__ dependencies
        # find the correct root node.
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] != key[0] or parent[1] == '__first__':
                    # Ignore __first__ references to the same app (#22325)
                    continue
                try:
                    self.graph.add_dependency(migration, key, parent)
                except NodeNotFoundError as e:
                    # Since we added "key" to the nodes before this implies
                    # "parent" is not in there. To make the raised exception
                    # more understandable we check if parent could have been
                    # replaced but hasn't (eg partially applied squashed
                    # migration)
                    _reraise_missing_dependency(migration, parent, e)
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] == key[0]:
                    # Internal dependencies already added.
                    continue
                parent = self.check_key(parent, key[0])
                if parent is not None:
                    try:
                        self.graph.add_dependency(migration, key, parent)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "parent" is not in there.
                        _reraise_missing_dependency(migration, parent, e)
            for child in migration.run_before:
                child = self.check_key(child, key[0])
                if child is not None:
                    try:
                        self.graph.add_dependency(migration, child, key)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "child" is not in there.
                        _reraise_missing_dependency(migration, child, e)
try:
    from django.conf import settings
    from django.core.exceptions import ImproperlyConfigured
    from django.contrib.contenttypes.models import ContentType
    from django.db import DEFAULT_DB_ALIAS, connections, migrations, models
    from django.db.migrations.recorder import MigrationRecorder
    import django.db.models.deletion
except ImportError as error:
    print(error)

# Fix a bad `social_django` migration.
try:
    BAD_MIGRATION = ('default', '0004_auto_20160423_0400')
    recorder = MigrationRecorder(connections[DEFAULT_DB_ALIAS])
    applied = recorder.applied_migrations()

    if applied and (BAD_MIGRATION not in applied):
        recorder.record_applied(*BAD_MIGRATION)
except (NameError, ImproperlyConfigured) as error:
    print(error)


class Migration(migrations.Migration):

    dependencies = [
        ('api_v3', '0008_v1_to_v2_attachments'),
    ]

    operations = [
        migrations.RunPython(lambda _a, _s: ContentType.objects.filter(
Beispiel #35
0
 def build_graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     You'll need to rebuild the graph if you apply migrations. This isn't
     usually a problem as generally migration stuff runs in a one-shot process.
     """
     # Load disk data
     self.load_disk()
     # Load database data
     if self.connection is None:
         self.applied_migrations = set()
     else:
         recorder = MigrationRecorder(self.connection)
         self.applied_migrations = recorder.applied_migrations()
     # To start, populate the migration graph with nodes for ALL migrations
     # and their dependencies. Also make note of replacing migrations at this step.
     self.graph = MigrationGraph()
     self.replacements = {}
     for key, migration in self.disk_migrations.items():
         self.graph.add_node(key, migration)
         # Internal (aka same-app) dependencies.
         self.add_internal_dependencies(key, migration)
         # Replacing migrations.
         if migration.replaces:
             self.replacements[key] = migration
     # Add external dependencies now that the internal ones have been resolved.
     for key, migration in self.disk_migrations.items():
         self.add_external_dependencies(key, migration)
     # Carry out replacements where possible.
     for key, migration in self.replacements.items():
         # Get applied status of each of this migration's replacement targets.
         applied_statuses = [(target in self.applied_migrations) for target in migration.replaces]
         # Ensure the replacing migration is only marked as applied if all of
         # its replacement targets are.
         if all(applied_statuses):
             self.applied_migrations.add(key)
         else:
             self.applied_migrations.discard(key)
         # A replacing migration can be used if either all or none of its
         # replacement targets have been applied.
         if all(applied_statuses) or (not any(applied_statuses)):
             self.graph.remove_replaced_nodes(key, migration.replaces)
         else:
             # This replacing migration cannot be used because it is partially applied.
             # Remove it from the graph and remap dependencies to it (#25945).
             self.graph.remove_replacement_node(key, migration.replaces)
     # Ensure the graph is consistent.
     try:
         self.graph.validate_consistency()
     except NodeNotFoundError as exc:
         # Check if the missing node could have been replaced by any squash
         # migration but wasn't because the squash migration was partially
         # applied before. In that case raise a more understandable exception
         # (#23556).
         # Get reverse replacements.
         reverse_replacements = {}
         for key, migration in self.replacements.items():
             for replaced in migration.replaces:
                 reverse_replacements.setdefault(replaced, set()).add(key)
         # Try to reraise exception with more detail.
         if exc.node in reverse_replacements:
             candidates = reverse_replacements.get(exc.node, set())
             is_replaced = any(candidate in self.graph.nodes for candidate in candidates)
             if not is_replaced:
                 tries = ', '.join('%s.%s' % c for c in candidates)
                 exc_value = NodeNotFoundError(
                     "Migration {0} depends on nonexistent node ('{1}', '{2}'). "
                     "Django tried to replace migration {1}.{2} with any of [{3}] "
                     "but wasn't able to because some of the replaced migrations "
                     "are already applied.".format(
                         exc.origin, exc.node[0], exc.node[1], tries
                     ),
                     exc.node
                 )
                 exc_value.__cause__ = exc
                 if not hasattr(exc, '__traceback__'):
                     exc.__traceback__ = sys.exc_info()[2]
                 six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2])
         raise exc
Beispiel #36
0
 def build_graph(self):
     """
     Builds a migration dependency graph using both the disk and database.
     You'll need to rebuild the graph if you apply migrations. This isn't
     usually a problem as generally migration stuff runs in a one-shot process.
     """
     # Load disk data
     self.load_disk()
     # Load database data
     recorder = MigrationRecorder(self.connection)
     self.applied_migrations = recorder.applied_migrations()
     # Do a first pass to separate out replacing and non-replacing migrations
     normal = {}
     replacing = {}
     for key, migration in self.disk_migrations.items():
         if migration.replaces:
             replacing[key] = migration
         else:
             normal[key] = migration
     # Calculate reverse dependencies - i.e., for each migration, what depends on it?
     # This is just for dependency re-pointing when applying replacements,
     # so we ignore run_before here.
     reverse_dependencies = {}
     for key, migration in normal.items():
         for parent in migration.dependencies:
             reverse_dependencies.setdefault(parent, set()).add(key)
     # Carry out replacements if we can - that is, if all replaced migrations
     # are either unapplied or missing.
     for key, migration in replacing.items():
         # Ensure this replacement migration is not in applied_migrations
         self.applied_migrations.discard(key)
         # Do the check. We can replace if all our replace targets are
         # applied, or if all of them are unapplied.
         applied_statuses = [(target in self.applied_migrations) for target in migration.replaces]
         can_replace = all(applied_statuses) or (not any(applied_statuses))
         if not can_replace:
             continue
         # Alright, time to replace. Step through the replaced migrations
         # and remove, repointing dependencies if needs be.
         for replaced in migration.replaces:
             if replaced in normal:
                 # We don't care if the replaced migration doesn't exist;
                 # the usage pattern here is to delete things after a while.
                 del normal[replaced]
             for child_key in reverse_dependencies.get(replaced, set()):
                 if child_key in migration.replaces:
                     continue
                 normal[child_key].dependencies.remove(replaced)
                 normal[child_key].dependencies.append(key)
         normal[key] = migration
         # Mark the replacement as applied if all its replaced ones are
         if all(applied_statuses):
             self.applied_migrations.add(key)
     # Finally, make a graph and load everything into it
     self.graph = MigrationGraph()
     for key, migration in normal.items():
         self.graph.add_node(key, migration)
     for key, migration in normal.items():
         for parent in migration.dependencies:
             # Special-case __first__, which means "the first migration" for
             # migrated apps, and is ignored for unmigrated apps. It allows
             # makemigrations to declare dependencies on apps before they
             # even have migrations.
             if parent[1] == "__first__" and parent not in self.graph:
                 if parent[0] in self.unmigrated_apps:
                     # This app isn't migrated, but something depends on it.
                     # The models will get auto-added into the state, though
                     # so we're fine.
                     continue
                 elif parent[0] in self.migrated_apps:
                     parent = list(self.graph.root_nodes(parent[0]))[0]
                 else:
                     raise ValueError("Dependency on unknown app %s" % parent[0])
             if parent is not None:
                 self.graph.add_dependency(key, parent)
Beispiel #37
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations, DEFAULT_DB_ALIAS, connections
from django.db.migrations.recorder import MigrationRecorder
import django.db.models.deletion
from django.conf import settings


connection = connections[DEFAULT_DB_ALIAS]
recorder = MigrationRecorder(connection)
linaro_django_xmlrpc_applied = False
lava_scheduler_app_applied = False
for app, name in recorder.applied_migrations():
    if app == 'linaro_django_xmlrpc' and name == '0001_initial':
        linaro_django_xmlrpc_applied = True
    if app == 'lava_scheduler_app' and name == '0001_initial':
        lava_scheduler_app_applied = True
if not linaro_django_xmlrpc_applied and lava_scheduler_app_applied:
    recorder.record_applied('linaro_django_xmlrpc', '0001_initial')


class Migration(migrations.Migration):

    dependencies = [
        ('auth', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('linaro_django_xmlrpc', '__first__'),
        ('dashboard_app', '__first__'),
    ]
Beispiel #38
0
 def build_graph(self):
     """
     Build a migration dependency graph using both the disk and database.
     You'll need to rebuild the graph if you apply migrations. This isn't
     usually a problem as generally migration stuff runs in a one-shot process.
     """
     # Load disk data
     self.load_disk()
     # Load database data
     if self.connection is None:
         self.applied_migrations = {}
     else:
         recorder = MigrationRecorder(self.connection)
         self.applied_migrations = recorder.applied_migrations()
     # To start, populate the migration graph with nodes for ALL migrations
     # and their dependencies. Also make note of replacing migrations at this step.
     self.graph = MigrationGraph()
     self.replacements = {}
     for key, migration in self.disk_migrations.items():
         self.graph.add_node(key, migration)
         # Replacing migrations.
         if migration.replaces:
             self.replacements[key] = migration
     for key, migration in self.disk_migrations.items():
         # Internal (same app) dependencies.
         self.add_internal_dependencies(key, migration)
     # Add external dependencies now that the internal ones have been resolved.
     for key, migration in self.disk_migrations.items():
         self.add_external_dependencies(key, migration)
     # Carry out replacements where possible and if enabled.
     if self.replace_migrations:
         for key, migration in self.replacements.items():
             # Get applied status of each of this migration's replacement
             # targets.
             applied_statuses = [(target in self.applied_migrations)
                                 for target in migration.replaces]
             # The replacing migration is only marked as applied if all of
             # its replacement targets are.
             if all(applied_statuses):
                 self.applied_migrations[key] = migration
             else:
                 self.applied_migrations.pop(key, None)
             # A replacing migration can be used if either all or none of
             # its replacement targets have been applied.
             if all(applied_statuses) or (not any(applied_statuses)):
                 self.graph.remove_replaced_nodes(key, migration.replaces)
             else:
                 # This replacing migration cannot be used because it is
                 # partially applied. Remove it from the graph and remap
                 # dependencies to it (#25945).
                 self.graph.remove_replacement_node(key, migration.replaces)
     # Ensure the graph is consistent.
     try:
         self.graph.validate_consistency()
     except NodeNotFoundError as exc:
         # Check if the missing node could have been replaced by any squash
         # migration but wasn't because the squash migration was partially
         # applied before. In that case raise a more understandable exception
         # (#23556).
         # Get reverse replacements.
         reverse_replacements = {}
         for key, migration in self.replacements.items():
             for replaced in migration.replaces:
                 reverse_replacements.setdefault(replaced, set()).add(key)
         # Try to reraise exception with more detail.
         if exc.node in reverse_replacements:
             candidates = reverse_replacements.get(exc.node, set())
             is_replaced = any(candidate in self.graph.nodes
                               for candidate in candidates)
             if not is_replaced:
                 tries = ', '.join('%s.%s' % c for c in candidates)
                 raise NodeNotFoundError(
                     "Migration {0} depends on nonexistent node ('{1}', '{2}'). "
                     "Django tried to replace migration {1}.{2} with any of [{3}] "
                     "but wasn't able to because some of the replaced migrations "
                     "are already applied.".format(exc.origin, exc.node[0],
                                                   exc.node[1], tries),
                     exc.node) from exc
         raise
     self.graph.ensure_not_cyclic()
Beispiel #39
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations, DEFAULT_DB_ALIAS, connections
from django.db.migrations.recorder import MigrationRecorder
import django.db.models.deletion
from django.conf import settings
import lava_scheduler_app.models

connection = connections[DEFAULT_DB_ALIAS]
recorder = MigrationRecorder(connection)
linaro_django_xmlrpc_applied = False
lava_scheduler_app_applied = False
for app, name in recorder.applied_migrations():
    if app == 'linaro_django_xmlrpc' and name == '0001_initial':
        linaro_django_xmlrpc_applied = True
    if app == 'lava_scheduler_app' and name == '0001_initial':
        lava_scheduler_app_applied = True
if not linaro_django_xmlrpc_applied and lava_scheduler_app_applied:
    recorder.record_applied('linaro_django_xmlrpc', '0001_initial')


class Migration(migrations.Migration):

    dependencies = [
        ('auth', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('linaro_django_xmlrpc', '__first__'),
        ('dashboard_app', '__first__'),
    ]
Beispiel #40
0
def app_schema_version(app_label):
    recorder = MigrationRecorder(connection)
    applied_migrations = sorted(
        (x[1] for x in recorder.applied_migrations() if x[0] == app_label))
    return calculate_checksum_str(applied_migrations)
    def build_graph(self):  # pragma: no cover
        """
        Builds a migration dependency graph using both the disk and database.
        You'll need to rebuild the graph if you apply migrations. This isn't
        usually a problem as generally migration stuff runs in a one-shot
        process.
        """
        # Load disk data
        self.load_disk()
        # Load database data
        if self.connection is None:
            self.applied_migrations = set()
        else:
            recorder = MigrationRecorder(self.connection)
            self.applied_migrations = recorder.applied_migrations()
        # Do first pass to separate out replacing and non-replacing migrations
        normal = {}
        replacing = {}
        for key, migration in self.disk_migrations.items():
            if migration.replaces:
                replacing[key] = migration
            else:
                normal[key] = migration
        # Calculate reverse dependencies - i.e., for each migration,
        # what depends on it?
        # This is just for dependency re-pointing when applying replacements,
        # so we ignore run_before here.
        reverse_dependencies = {}
        for key, migration in normal.items():
            for parent in migration.dependencies:
                reverse_dependencies.setdefault(parent, set()).add(key)
        # Remember the possible replacements to generate more meaningful error
        # messages
        reverse_replacements = {}
        for key, migration in replacing.items():
            for replaced in migration.replaces:
                reverse_replacements.setdefault(replaced, set()).add(key)
        # Carry out replacements if we can - that is, if all replaced migration
        # are either unapplied or missing.
        for key, migration in replacing.items():
            # Ensure this replacement migration is not in applied_migrations
            self.applied_migrations.discard(key)
            # Do the check. We can replace if all our replace targets are
            # applied, or if all of them are unapplied.
            applied = self.applied_migrations
            replaces = migration.replaces
            applied_statuses = [(target in applied) for target in replaces]
            can_replace = all(applied_statuses) or (not any(applied_statuses))
            if not can_replace:
                continue
            # Alright, time to replace. Step through the replaced migrations
            # and remove, repointing dependencies if needs be.
            for replaced in migration.replaces:
                if replaced in normal:
                    # We don't care if the replaced migration doesn't exist;
                    # the usage pattern here is to delete things after a while.
                    del normal[replaced]
                for child_key in reverse_dependencies.get(replaced, set()):
                    if child_key in migration.replaces:
                        continue
                    # List of migrations whose dependency on `replaced` needs
                    # to be updated to a dependency on `key`.
                    to_update = []
                    # Child key may itself be replaced, in which case it might
                    # not be in `normal` anymore (depending on whether we've
                    # processed its replacement yet). If it's present, we go
                    # ahead and update it; it may be deleted later on if it is
                    # replaced, but there's no harm in updating it regardless.
                    if child_key in normal:
                        to_update.append(normal[child_key])
                    # If the child key is replaced, we update its replacement's
                    # dependencies too, if necessary. (We don't know if this
                    # replacement will actually take effect or not, but either
                    # way it's OK to update the replacing migration).
                    if child_key in reverse_replacements:
                        for replaces_ck in reverse_replacements[child_key]:
                            if replaced in replacing[replaces_ck].dependencies:
                                to_update.append(replacing[replaces_ck])
                    # Actually perform the dependency update on all migrations
                    # that require it.
                    for migration_needing_update in to_update:
                        migration_needing_update.dependencies.remove(replaced)
                        migration_needing_update.dependencies.append(key)
            normal[key] = migration
            # Mark the replacement as applied if all its replaced ones are
            if all(applied_statuses):
                self.applied_migrations.add(key)
        # Store the replacement migrations for later checks
        self.replacements = replacing
        # Finally, make a graph and load everything into it
        self.graph = MigrationGraph()
        for key, migration in normal.items():
            self.graph.add_node(key, migration)

        def _reraise_missing_dependency(migration, missing, exc):
            """
            Checks if ``missing`` could have been replaced by any squash
            migration but wasn't because the the squash migration was partially
            applied before. In that case raise a more understandable exception.
            #23556
            """
            if missing in reverse_replacements:
                candidates = reverse_replacements.get(missing, set())
                nodes = self.graph.nodees
                is_replaced = \
                    any(candidate in nodes for candidate in candidates)
                if not is_replaced:
                    tries = ', '.join('%s.%s' % c for c in candidates)
                    exc_value = NodeNotFoundError(
                        "Migration {0} depends on nonexistent node "
                        "('{1}', '{2}'). Django tried to replace migration "
                        "{1}.{2} with any of [{3}] but wasn't able to because "
                        "some of the replaced migrations are already "
                        "applied.".format(
                            migration, missing[0], missing[1], tries
                        ),
                        missing)
                    exc_value.__cause__ = exc
                    six.reraise(
                        NodeNotFoundError, exc_value, sys.exc_info()[2])
            raise exc

        # Add all internal dependencies first to ensure __first__ dependencies
        # find the correct root node.
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] != key[0] or parent[1] == '__first__':
                    # Ignore __first__ references to the same app (#22325)
                    continue
                try:
                    self.graph.add_dependency(migration, key, parent)
                except NodeNotFoundError as e:
                    # Since we added "key" to the nodes before this implies
                    # "parent" is not in there. To make the raised exception
                    # more understandable we check if parent could have been
                    # replaced but hasn't (eg partially applied squashed
                    # migration)
                    _reraise_missing_dependency(migration, parent, e)
        for key, migration in normal.items():
            for parent in migration.dependencies:
                if parent[0] == key[0]:
                    # Internal dependencies already added.
                    continue
                parent = self.check_key(parent, key[0])
                if parent is not None:
                    try:
                        self.graph.add_dependency(migration, key, parent)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "parent" is not in there.
                        _reraise_missing_dependency(migration, parent, e)
            for child in migration.run_before:
                child = self.check_key(child, key[0])
                if child is not None:
                    try:
                        self.graph.add_dependency(migration, child, key)
                    except NodeNotFoundError as e:
                        # Since we added "key" to the nodes before this implies
                        # "child" is not in there.
                        _reraise_missing_dependency(migration, child, e)