Migrate: Migrate.Up() errors out if the latest schema is in use

Created on 7 Sep 2018  路  4Comments  路  Source: golang-migrate/migrate

Migrate.Up() errors out if the currently active schema matches the latest schema version.

Steps to Reproduce
My migrations look like this:

1_initialize_tables.down.sql

DROP roles_test;
DROP permissions_test;

1_initialize_tables.up.sql

CREATE TABLE permissions_test (
    definition STRING(MAX) NOT NULL,
) PRIMARY KEY (definition);
CREATE TABLE roles_test (
    `parent` STRING(MAX) NOT NULL,
    role_id STRING(MAX) NOT NULL,
) PRIMARY KEY (`parent`, role_id);

I have code that looks like this:

migrator, err := migrate.New(
 "file://migrations",
  "spanner://projects/my-project/instances/main-instance/databases/my-database")
if err != nil {
  log.Fatalf("Unable to instantiate the database schema migrator - %v", err)
}   

// Migrate up to the latest active version
if err := migrator.Up(); err != nil {
  log.Fatalf("Unable to migrate up to the latest database schema - %v", err)
}

And I get the error:

Unable to migrate up to the latest database schema - no change

Expected Behavior
I would expect Migrate.Up() to not return an error if the latest schema is in use. At minimum it should return an ErrAlreadyUpToDate or something similar. If this is not the intended use of this method, better documentation should be made to demonstrate how this functionality is best achieved with the current migrate API.

Migrate Version
v3.5.1 - Go Client

Loaded Source Drivers
file

Loaded Database Drivers
spanner

Additional context
I've ran Migrate.Up() once which created an entry in the SchemaMigrations table and a row now exists that looks like this:

| Version | Dirty |
|---------|-------|
| 1       | False |

The second time I start my service up Migrate.Up() fails because the currently active version is the latest one.

Most helpful comment

I'm sorry, but I still don't see how "no change" should be an error. And checking the error for a certain type does not seem like the right solution to me here. Is there any specific reason it is done like that? From my understanding it could just be logged away.

All 4 comments

Have you asserted that err != migrate.ErrNoChange?

@dhui Oh man, I didn't even see that! I'm sorry. That fixes it!

I'm sorry, but I still don't see how "no change" should be an error. And checking the error for a certain type does not seem like the right solution to me here. Is there any specific reason it is done like that? From my understanding it could just be logged away.

I'm sorry, but I still don't see how "no change" should be an error.
...
Is there any specific reason it is done like that?

This decision predates me.

And checking the error for a certain type does not seem like the right solution to me here.

This pattern is also used in the io.Reader interface e.g. io.EOF

From my understanding it could just be logged away.

Unfortunately, logging in Go leaves a lot to be desired. e.g. every package has their own way of handling logging... Until there's a standard configurable way to log messages at different levels, migrate will avoid logging in the library and only use errors.

Was this page helpful?
0 / 5 - 0 ratings