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

如何将Go中embed.FS的硬编码路径改为传入参数?

解决方案

要实现动态传入迁移文件路径,你需要放弃编译时的//go:embed指令,改用运行时读取本地文件系统的方式。os.DirFS本身仅提供目录级的文件系统访问,无法直接处理通配符匹配,推荐直接使用migrate库原生支持的本地文件源来简化逻辑。

修改后的代码

package main

import (
    "log"
    "path/filepath"

    "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/database/postgres" // 根据你的数据库类型替换
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    // 可替换为命令行参数传入,比如使用flag包解析
    migrationDir := "./migrations"
    if err := migrate(migrationDir); err != nil {
        log.Fatal(err)
    }
    log.Println("done")
}

func migrate(migrationDir string) error {
    // 构建file://格式的数据源URL,适配migrate的file源要求
    sourceURL := "file://" + filepath.Clean(migrationDir)
    
    // 替换为你的实际数据库连接URL
    dbURL := "postgres://user:password@localhost:5432/dbname?sslmode=disable"
    
    m, err := migrate.New(sourceURL, dbURL)
    if err != nil {
        return err
    }
    
    // 执行迁移,若无需回滚可直接用Up();如需回滚可改用Down()
    if err := m.Up(); err != nil && err != migrate.ErrNoChange {
        return err
    }
    
    return nil
}

关于os.DirFS的问题补充

如果需要坚持使用iofs接口风格,你可以结合filepath.Glob来筛选目录下的.sql文件,但这需要额外处理文件读取逻辑,不如直接用migrate的file源便捷:

import "path/filepath"

// 示例:手动筛选目录下的所有.sql文件
files, err := filepath.Glob(filepath.Join(migrationDir, "*.sql"))
if err != nil {
    // 处理错误
}

内容的提问来源于stack exchange,提问作者mikolaj semeniuk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:01:00