Example #1
0
    def test_clean(self):
        Migration.create_table(if_not_exists=True).run_sync()

        real_migration_ids = [
            "2020-12-17T18:44:30",
            "2020-12-17T18:44:39",
            "2020-12-17T18:44:44",
        ]

        orphaned_migration_id = "2010-01-101T00:00:00"

        migration_ids = real_migration_ids + [orphaned_migration_id]

        Migration.insert(
            *[Migration(name=i, app_name="example_app") for i in migration_ids]
        ).run_sync()

        run_sync(clean(app_name="example_app", auto_agree=True))

        remaining_rows = (
            Migration.select(Migration.name)
            .where(Migration.app_name == "example_app")
            .output(as_list=True)
            .order_by(Migration.name)
            .run_sync()
        )
        self.assertEqual(remaining_rows, real_migration_ids)

        Migration.alter().drop_table(if_exists=True).run_sync()
Example #2
0
    def get_migration_ids_to_remove(self) -> t.List[str]:
        """
        Returns a list of migration ID strings, which are rows in the table,
        but don't have a corresponding migration module on disk.
        """
        app_config = self.get_app_config(app_name=self.app_name)

        migration_module_dict = self.get_migration_modules(
            folder_path=app_config.migrations_folder_path
        )

        # The migration IDs which are in migration modules.
        migration_ids = self.get_migration_ids(
            migration_module_dict=migration_module_dict
        )

        query = (
            Migration.select(Migration.name)
            .where(Migration.app_name == self.app_name)
            .output(as_list=True)
        )

        if len(migration_ids) > 0:
            query = query.where(Migration.name.not_in(migration_ids))

        migration_ids_to_remove = query.run_sync()
        return migration_ids_to_remove
Example #3
0
    async def run_migrations(self, app_config: AppConfig) -> MigrationResult:
        already_ran = await Migration.get_migrations_which_ran(
            app_name=app_config.app_name)

        migration_modules: t.Dict[
            str, MigrationModule] = self.get_migration_modules(
                app_config.migrations_folder_path)

        ids = self.get_migration_ids(migration_modules)
        n = len(ids)
        print(f"👍 {n} migration{'s' if n != 1 else ''} already complete")

        havent_run = sorted(set(ids) - set(already_ran))
        if len(havent_run) == 0:
            # Make sure this still appears successful, as we don't want this
            # to appear as an error in automated scripts.
            message = "🏁 No migrations need to be run"
            print(message)
            return MigrationResult(success=True, message=message)
        else:
            n = len(havent_run)
            print(f"⏩ {n} migration{'s' if n != 1 else ''} not yet run")

        if self.migration_id == "all":
            subset = havent_run
        elif self.migration_id == "1":
            subset = havent_run[:1]
        else:
            try:
                index = havent_run.index(self.migration_id)
            except ValueError:
                message = f"{self.migration_id} is unrecognised"
                print(message, file=sys.stderr)
                return MigrationResult(success=False, message=message)
            else:
                subset = havent_run[:index + 1]

        if subset:
            n = len(subset)
            print(f"🚀 Running {n} migration{'s' if n != 1 else ''}:")

            for _id in subset:
                if self.fake:
                    print(f"- {_id}: faked! ⏭️")
                else:
                    migration_module = migration_modules[_id]
                    response = await migration_module.forwards()

                    if isinstance(response, MigrationManager):
                        await response.run()

                    print("ok! ✔️")

                await Migration.insert().add(
                    Migration(name=_id, app_name=app_config.app_name)).run()

        return MigrationResult(success=True, message="migration succeeded")
Example #4
0
    async def run_migrations(self, app_config: AppConfig) -> MigrationResult:
        already_ran = await Migration.get_migrations_which_ran(
            app_name=self.app_name)

        migration_modules: t.Dict[
            str, MigrationModule] = self.get_migration_modules(
                app_config.migrations_folder_path)

        ids = self.get_migration_ids(migration_modules)
        print(f"All migration ids = {ids}")

        havent_run = sorted(set(ids) - set(already_ran))
        print(f"Haven't run = {havent_run}")

        if len(havent_run) == 0:
            # Make sure this still appears successful, as we don't want this
            # to appear as an error in automated scripts.
            message = "No migrations left to run!"
            print(message)
            return MigrationResult(success=True, message=message)

        if self.migration_id == "all":
            subset = havent_run
        elif self.migration_id == "1":
            subset = havent_run[:1]
        else:
            try:
                index = havent_run.index(self.migration_id)
            except ValueError:
                message = f"{self.migration_id} is unrecognised"
                print(message, file=sys.stderr)
                return MigrationResult(success=False, message=message)
            else:
                subset = havent_run[:index + 1]

        for _id in subset:
            if self.fake:
                print(f"Faked {_id}")
            else:
                migration_module = migration_modules[_id]
                response = await migration_module.forwards()

                if isinstance(response, MigrationManager):
                    await response.run()

                print(f"-> Ran {_id}")

            await Migration.insert().add(
                Migration(name=_id, app_name=self.app_name)).run()

        return MigrationResult(success=True, message="Ran successfully")
Example #5
0
    def test_forwards_fake(self):
        """
        Test running the migrations if they've already run.
        """
        run_sync(
            forwards(app_name="example_app", migration_id="all", fake=True))

        for table_class in TABLE_CLASSES:
            self.assertTrue(not table_class.table_exists().run_sync())

        ran_migration_names = (Migration.select(
            Migration.name).output(as_list=True).run_sync())

        self.assertEqual(
            ran_migration_names,
            # TODO - rather than hardcoding, might fetch these dynamically.
            [
                "2020-12-17T18:44:30",
                "2020-12-17T18:44:39",
                "2020-12-17T18:44:44",
            ],
        )
    def test_forwards_fake(self):
        """
        Test running the migrations if they've already run.
        """
        run_sync(forwards(app_name="music", migration_id="all", fake=True))

        for table_class in TABLE_CLASSES:
            self.assertTrue(not table_class.table_exists().run_sync())

        ran_migration_names = (Migration.select(
            Migration.name).output(as_list=True).run_sync())

        self.assertEqual(
            ran_migration_names,
            # TODO - rather than hardcoding, might fetch these dynamically.
            [
                "2020-12-17T18:44:30",
                "2020-12-17T18:44:39",
                "2020-12-17T18:44:44",
                "2021-07-25T22:38:48:009306",
                "2021-09-06T13:58:23:024723",
                "2021-11-13T14:01:46:114725",
            ],
        )
Example #7
0
 def test_migration_table(self):
     Migration.create_table().run_sync()
     Migration.select().run_sync()
     Migration.alter().drop_table().run_sync()
Example #8
0
 def tearDown(self):
     create_table_class("MyTable").alter().drop_table(
         if_exists=True).run_sync()
     Migration.alter().drop_table(if_exists=True).run_sync()
Example #9
0
 def test_migration_table(self):
     Migration.create_table(if_not_exists=True).run_sync()
     Migration.select().run_sync()
     Migration.alter().drop_table().run_sync()