使用golang-migrate与Docker PostgreSQL时出现‘no change’错误的解决
Golang数据库迁移报错:
no change 修复方案 问题场景
我有一个Golang项目,包含以下代码文件,运行主程序时触发数据库迁移报错。
代码文件
main.go
package main import ( "database/sql" "log" _ "github.com/jackc/pgx/v4/stdlib" dbmigration "github.com/rajcspsg/grpc-ms/unary/server/db" ) func main() { sqlDB, err := sql.Open("pgx", "postgres://postgres:postgres@localhost:5432/grpc?sslmode=disable") if err != nil { log.Fatalln("Can't connect to database: ", err) } dbmigration.Migrate(sqlDB) }
dbmigration.go
package dbmigration import ( "database/sql" "log" "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" _ "github.com/golang-migrate/migrate/v4/source/file" ) func Migrate(conn *sql.DB) { log.Println("Database migration start") m, err := migrate.New( "file://db/migrations", "postgres://user-name:strong-password@localhost:5432/postgres?sslmode=disable") if err != nil { log.Fatalln("Database migration failed: ", err) } if err := m.Down(); err != nil { log.Fatalln("Database migration(down) failed:", err) } if err := m.Up(); err != nil { log.Fatalln("Database migration(up) failed:", err) } log.Println("Database migration completed!!!") }
db/migrations/000_create_table_dummy.up.sql
CREATE TABLE IF NOT EXISTS DUMMY ( user_id UUID PRIMARY KEY, user_name TEXT NOT NULL, created_at TIMESTAMPZ, updated_at TIMESTAMPZ );
db/migrations/000_create_table_dummy.down.sql
DROP TABLE IF EXISTS DUMMY;
docker-compose.yml
version: "3.8" services: db: image: postgres container_name: local_pgdb4grpc restart: always ports: - "5432:5432" environment: POSTGRES_USER: user-name POSTGRES_PASSWORD: strong-password volumes: - local_pgdata:/var/lib/postgresql/data pgadmin: image: dpage/pgadmin4 container_name: pgadmin4_container4grpc restart: always ports: - "8888:80" environment: PGADMIN_DEFAULT_EMAIL: user-name@domain-name.com PGADMIN_DEFAULT_PASSWORD: strong-password volumes: - pgadmin-data:/var/lib/pgadmin volumes: local_pgdata: pgadmin-data:
错误信息
./bin/server 18:41:36 Database migration start 18:41:37 Database migration(down) failed: no change make: *** [Makefile:27: execute] Error 1
修复方案
1. 修正Down()错误处理逻辑
migrate.Down()在没有已应用的迁移记录时,会返回migrate.ErrNoChange,这是正常状态而非致命错误,不需要直接终止程序。修改dbmigration.go中的错误判断:
if err := m.Down(); err != nil && err != migrate.ErrNoChange { log.Fatalln("Database migration(down) failed:", err) }
2. 统一数据库连接信息
- 当前
main.go连接的是grpc数据库,但dbmigration.go连接的是默认的postgres数据库,两者不一致,需同步为同一个数据库(建议和main.go保持一致用grpc)。 main.go使用的用户名密码是postgres/postgres,但docker-compose.yml配置的是user-name/strong-password,需统一为docker-compose中的配置。
修改dbmigration.go的数据库DSN:
"postgres://user-name:strong-password@localhost:5432/grpc?sslmode=disable"
或者同步main.go的DSN:
sqlDB, err := sql.Open("pgx", "postgres://user-name:strong-password@localhost:5432/grpc?sslmode=disable")
3. 可选:调整迁移执行逻辑
如果不需要每次启动都先回滚再迁移,可以直接移除m.Down()调用,只保留m.Up(),避免不必要的回滚操作。
内容的提问来源于stack exchange,提问作者user51
相关产品推荐
相关产品推荐

