Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let's make resetting(squash) migrations EASY! #2724

Closed
jjangga0214 opened this issue Aug 13, 2019 · 1 comment · Fixed by #3072
Closed

Let's make resetting(squash) migrations EASY! #2724

jjangga0214 opened this issue Aug 13, 2019 · 1 comment · Fixed by #3072
Assignees
Labels
c/cli Related to CLI e/intermediate can be wrapped up in a week k/enhancement New feature or improve an existing feature p/medium non-urgent issues/features that are candidates for being included in one of the upcoming sprints

Comments

@jjangga0214
Copy link
Contributor

jjangga0214 commented Aug 13, 2019

Migration files can easily be piled up. So "squash" feature would be required in some projects. According to https://blog.hasura.io/resetting-hasura-migrations/, in order to squash, we should do

  1. Remove every migration files (rm migrations/*).
  2. Remove whole data from the table hdb_catalog.schema_migrations (TRUNCATE hdb_catalog.schema_migrations;)
  3. Pull the metadata (and optionally schema) from hasura.
  4. Apply the pulled metadata (and optionally schema) just back to hasura (with --skip-execution option as hasura obviously already have the metadata, but only needs "version" to be applied.)

Problems

In my humble opinion, there are these problems.

Inconsistency (high-level vs low-level migration tasks)

Users handle migration through cli. The high-level approach should be consistent. But suddenly having to take care about schema_migrations table is not enough abstract. So it does not give 'smooth' and 'expected' experience. I guess many even don't know schema_migrations, as docs(https://docs.hasura.io/1.0/graphql/manual/how-it-works/metadata-schema.html) only explicitly explains hdb_table, hdb_relationship, and hdb_permission, not schema_migrations and many others.

Somewhat hacky? (at least to me)

Users should specify --skip-execution. After they just pulled migrations files from hasura, they have to "pretend" applying migration only for writing a new row on schema_migrations. It makes me feel I am doing a "workaround" rather than a straight official way.

Too manual

There are total 4 manual steps for one "squash". These are cumbersome and error-prone.

"squash"ing does happen as projects grow. People obviously just don't want hundreds of migration files to be stacked, because it'd be inconvenient to open migration directory and it just simply looks not "neat". So the "squash" can't but happen and it should be automatic for convenience.

Solution

I suggest a command like

hasura migrate squash

which would safely execute the 4 steps automatically.

@jjangga0214 jjangga0214 changed the title [cli] Let's make resetting(squash) migrations EASY! Let's make resetting(squash) migrations EASY! Aug 13, 2019
@shahidhk shahidhk added c/cli Related to CLI e/intermediate can be wrapped up in a week good first issue Good for newcomers help wanted Good candidate for contribution. Community help wanted! k/enhancement New feature or improve an existing feature p/medium non-urgent issues/features that are candidates for being included in one of the upcoming sprints labels Aug 13, 2019
@heyrict
Copy link

heyrict commented Aug 24, 2019

Currently, to avoid inconsistency of database, I'm writing the migrations myself instead of using hasura console.

How do I squash migrations when using hasura console

  1. do several migrations in hasura console
  2. revert some migrations with hasura cli
    hasura migrate apply --down x
  3. concatenate up and down migration files
    cat `ls *.up.yaml | tail -n x`  > `ls *.up.yaml | tail -n 1`
    cat `ls *.down.yaml | tail -n x | tac` > `ls *.down.yaml | tail -n 1`
  4. do migrations again
    hasura migrate apply --up x

If you use a similar workflow as me, a simple bash function should help as a temporary workaround.

hasura_migrate_squash(){
    hasura migrate apply --down $1;
    cat `ls *.up.yaml | tail -n $1`  > `ls *.up.yaml | tail -n 1`;
    cat `ls *.down.yaml | tail -n $1 | tac` > `ls *.down.yaml | tail -n 1`;
    hasura migrate apply --up $1;
}

Another solution

Another solution I come up with is to add a squash option to hasura console.

  1. Check squash option.
  2. Do migration A. Console will generate a file [timestamp_A]_migration_A.*.yaml.
  3. Do migration B. Console will move [timestamp_A]_migration_A.*.yaml to [timestamp_A]_multiple_migrations.*.yaml or something like so, and concatenating the A and B migrations to this file.
    So the content of []multiple_migrations.up.yaml should be
    ...A
    ...B
    
    and content of []multiple_migrations.down.yaml should be
    ...B
    ...A
    

This solution suppose the developer has only one open window of hasura console, as the squash option is stored in the client (say, redux store).

@shark-h shark-h removed good first issue Good for newcomers help wanted Good candidate for contribution. Community help wanted! labels Sep 27, 2019
shahidhk pushed a commit that referenced this issue Oct 31, 2019
### Description
This PR introduces three new features:

- Support for a new migrations folder structure.
- Add `squash` command in preview.
- ~List of migrations on the Console and ability to squash them from console.~

#### New migrations folder structure

Starting with this commit, Hasura CLI supports a new directory structure for migrations folder and defaults to that for all new migrations created. 

Each migration will get a new directory with the name format `timestamp_name` and inside the directory, there will be four files:

```bash
└── migrations
    ├── 1572237730898_squashed
    │   ├── up.sql
    │   ├── up.yaml
    │   ├── down.yaml
    │   └── down.sql
```

Existing files old migration format `timestamp_name.up|down.yaml|sql` will continue to work alongside new migration files.

#### Squash command

Lots of users have expressed their interest in squashing migrations (see #2724 and #2254) and some even built [their own tools](https://github.com/domasx2/hasura-squasher) to do squash. In this PR, we take a systematic approach to squash migrations.

A new command called `migrate squash` is introduced. Note that this command is in **PREVIEW** and the correctness of squashed migration is not guaranteed (especially for down migrations). From our tests, **it works for most use cases**, but we have found some issues with squashing all the down migrations, partly because the console doesn't generate down migrations for all actions.

Hence, until we add an extensive test suite for squashing, we'll keep the command in preview. We recommend you to confirm the correctness yourself by diffing the SQL and Metadata before and after applying the squashed migrations (we're also thinking about embedding some checks into the command itself).

```bash
$ hasura migrate squash --help
(PREVIEW) Squash multiple migrations leading upto the latest one into a single migration file

Usage:
  hasura migrate squash [flags]

Examples:
  # NOTE: This command is in PREVIEW, correctness is not guaranteed and the usage may change.

  # squash all migrations from version 1572238297262 to the latest one:
  hasura migrate squash --from 1572238297262

Flags:
      --from uint             start squashing form this version
      --name string           name for the new squashed migration (default "squashed")
      --delete-source         delete the source files after squashing without any confirmation
```

### Affected components 
<!-- Remove non-affected components from the list -->

- CLI

### Related Issues
<!-- Please make sure you have an issue associated with this Pull Request -->
<!-- And then add `(close #<issue-no>)` to the pull request title -->
<!-- Add the issue number below (e.g. #234) -->
Close #2724, Close #2254, 

### Solution and Design
<!-- How is this issue solved/fixed? What is the design? -->
<!-- It's better if we elaborate -->

For the squash command, a state machine is implemented to track changes to Hasura metadata. After applying each action on the metadata state, a list of incremental changes is created.

### Steps to test and verify
1. Open console via cli and create some migrations.
2. Run `hasura migrate squash --from <version>`

### Limitations, known bugs & workarounds
<!-- Limitations of the PR, known bugs and suggested workarounds -->

<!-- Feel free to delete these comment lines -->
- The `squash` command is in preview
- Support for squashing from the console is WIP
- Support for squashing migrations that are not committed yet is planned.
- Un-tracking or dropping a table will cause inconsistent squashed down migration since console doesn't generate correct down migration.
- If cascade setting is set to `true` on any of the metadata action, generated migration may be wrong
polRk pushed a commit to polRk/graphql-engine that referenced this issue Feb 12, 2020
### Description
This PR introduces three new features:

- Support for a new migrations folder structure.
- Add `squash` command in preview.
- ~List of migrations on the Console and ability to squash them from console.~

#### New migrations folder structure

Starting with this commit, Hasura CLI supports a new directory structure for migrations folder and defaults to that for all new migrations created. 

Each migration will get a new directory with the name format `timestamp_name` and inside the directory, there will be four files:

```bash
└── migrations
    ├── 1572237730898_squashed
    │   ├── up.sql
    │   ├── up.yaml
    │   ├── down.yaml
    │   └── down.sql
```

Existing files old migration format `timestamp_name.up|down.yaml|sql` will continue to work alongside new migration files.

#### Squash command

Lots of users have expressed their interest in squashing migrations (see hasura#2724 and hasura#2254) and some even built [their own tools](https://github.com/domasx2/hasura-squasher) to do squash. In this PR, we take a systematic approach to squash migrations.

A new command called `migrate squash` is introduced. Note that this command is in **PREVIEW** and the correctness of squashed migration is not guaranteed (especially for down migrations). From our tests, **it works for most use cases**, but we have found some issues with squashing all the down migrations, partly because the console doesn't generate down migrations for all actions.

Hence, until we add an extensive test suite for squashing, we'll keep the command in preview. We recommend you to confirm the correctness yourself by diffing the SQL and Metadata before and after applying the squashed migrations (we're also thinking about embedding some checks into the command itself).

```bash
$ hasura migrate squash --help
(PREVIEW) Squash multiple migrations leading upto the latest one into a single migration file

Usage:
  hasura migrate squash [flags]

Examples:
  # NOTE: This command is in PREVIEW, correctness is not guaranteed and the usage may change.

  # squash all migrations from version 1572238297262 to the latest one:
  hasura migrate squash --from 1572238297262

Flags:
      --from uint             start squashing form this version
      --name string           name for the new squashed migration (default "squashed")
      --delete-source         delete the source files after squashing without any confirmation
```

### Affected components 
<!-- Remove non-affected components from the list -->

- CLI

### Related Issues
<!-- Please make sure you have an issue associated with this Pull Request -->
<!-- And then add `(close #<issue-no>)` to the pull request title -->
<!-- Add the issue number below (e.g. hasura#234) -->
Close hasura#2724, Close hasura#2254, 

### Solution and Design
<!-- How is this issue solved/fixed? What is the design? -->
<!-- It's better if we elaborate -->

For the squash command, a state machine is implemented to track changes to Hasura metadata. After applying each action on the metadata state, a list of incremental changes is created.

### Steps to test and verify
1. Open console via cli and create some migrations.
2. Run `hasura migrate squash --from <version>`

### Limitations, known bugs & workarounds
<!-- Limitations of the PR, known bugs and suggested workarounds -->

<!-- Feel free to delete these comment lines -->
- The `squash` command is in preview
- Support for squashing from the console is WIP
- Support for squashing migrations that are not committed yet is planned.
- Un-tracking or dropping a table will cause inconsistent squashed down migration since console doesn't generate correct down migration.
- If cascade setting is set to `true` on any of the metadata action, generated migration may be wrong
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c/cli Related to CLI e/intermediate can be wrapped up in a week k/enhancement New feature or improve an existing feature p/medium non-urgent issues/features that are candidates for being included in one of the upcoming sprints
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants