Example #1
0
def _main() -> None:
    """
    This method takes the output of `git diff --name-status master snuba/migrations` and
    runs `snuba migrations run -dry-run with the proper parameters`, for a CI action
    """
    diff_result = subprocess.run(
        [
            "git",
            "diff",
            "--diff-filter=AM",
            "--name-only",
            "origin/master",
            "--",
            "snuba/migrations/snuba_migrations/*/[0-9]*.py",
        ],
        stdout=subprocess.PIPE,
        text=True,
    )
    if diff_result.returncode != 0:
        raise ExecError(diff_result.stdout)
    else:
        lines = diff_result.stdout.splitlines()
        if len(lines) > 0:
            print("-- start migrations")
            print()
        for line in lines:
            migration_filename = os.path.basename(line)
            migration_group = MigrationGroup(os.path.basename(os.path.dirname(line)))
            migration_id, _ = os.path.splitext(migration_filename)

            runner = Runner()
            migration_key = MigrationKey(migration_group, migration_id)
            print(f"-- migration {migration_group.value} : {migration_id}")
            runner.run_migration(migration_key, dry_run=True)
            print(f"-- end migration {migration_group.value} : {migration_id}")
Example #2
0
def run(group: str, migration_id: str, force: bool, fake: bool,
        dry_run: bool) -> None:
    """
    Runs a single migration.
    --force must be passed in order to run blocking migrations.
    --fake marks a migration as completed without running anything.

    Migrations that are already in an in-progress or completed status will not be run.
    """
    if not dry_run:
        check_clickhouse_connections()

    runner = Runner()
    migration_group = MigrationGroup(group)
    migration_key = MigrationKey(migration_group, migration_id)

    if dry_run:
        runner.run_migration(migration_key, dry_run=True)
        return

    try:
        if fake:
            click.confirm(
                "This will mark the migration as completed without actually running it. Your database may be in an invalid state. Are you sure?",
                abort=True,
            )
        runner.run_migration(migration_key, force=force, fake=fake)
    except MigrationError as e:
        raise click.ClickException(str(e))

    click.echo(f"Finished running migration {migration_key}")
Example #3
0
    def _get_migration_status(self) -> Mapping[MigrationKey, Status]:
        data: MutableMapping[MigrationKey, Status] = {}
        migration_groups = (
            "("
            + (
                ", ".join(
                    [
                        escape_string(group.value)
                        for group in get_active_migration_groups()
                    ]
                )
            )
            + ")"
        )

        try:
            for row in self.__connection.execute(
                f"SELECT group, migration_id, status FROM {self.__table_name} FINAL WHERE group IN {migration_groups}"
            ):
                group_name, migration_id, status_name = row
                data[MigrationKey(MigrationGroup(group_name), migration_id)] = Status(
                    status_name
                )
        except ClickhouseError as e:
            # If the table wasn't created yet, no migrations have started.
            if e.code != errors.ErrorCodes.UNKNOWN_TABLE:
                raise e

        return data
Example #4
0
def reverse(group: str, migration_id: str, force: bool, fake: bool,
            dry_run: bool) -> None:
    """
    Reverses a single migration.

    --force is required to reverse an already completed migration.
    --fake marks a migration as reversed without doing anything.
    """
    if not dry_run:
        check_clickhouse_connections()
    runner = Runner()
    migration_group = MigrationGroup(group)
    migration_key = MigrationKey(migration_group, migration_id)

    if dry_run:
        runner.reverse_migration(migration_key, dry_run=True)
        return

    try:
        if fake:
            click.confirm(
                "This will mark the migration as not started without actually reversing it. Your database may be in an invalid state. Are you sure?",
                abort=True,
            )
        runner.reverse_migration(migration_key, force=force, fake=fake)
    except MigrationError as e:
        raise click.ClickException(str(e))

    click.echo(f"Finished reversing migration {migration_key}")