You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:25:00