为了账号安全,请及时绑定邮箱和手机立即绑定

使用 env 文件时 Golang 数据库/sql 不连接

使用 env 文件时 Golang 数据库/sql 不连接

Go
开满天机 2023-02-21 13:20:08
这完美地工作并且数据库已连接,没有问题。但是我不想在函数中对我的值进行硬编码,因此我使用的是 env 文件。但是使用 os.getenv 不会连接到数据库。package mainimport (    "database/sql"    "fmt"    _ "github.com/lib/pq")const (    host     = "localhost"    port     = 5432    user     = "bond"    password = "password"    dbname   = "bookstore")func main() {    psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+        "password=%s dbname=%s sslmode=disable",        host, port, user, password, dbname)    db, err := sql.Open("postgres", psqlInfo)    if err != nil {        panic(err)    }    defer db.Close()    err = db.Ping()    if err != nil {        panic(err)    }    fmt.Println("You connected to your database.")}以下代码给出了错误 -panic: pq: password authentication failed for user "bond"var (    host     = "localhost"    port     = 5432    user     = "bond"    password = os.Getenv("DATABASE_PWD")    dbname   = "bookstore")为什么会这样?
查看完整描述

2 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

看起来你正在做这样的事情(游乐场):

var (

    env      = make(map[string]string) // Simulated environoment

    password = env["DATABASE_PWD"]

)


func init() {

    // Simulate loading .env file (godotenv.Load())

    env["DATABASE_PWD"] = "foo"

}


func main() {

    fmt.Println(password) // Outputs a blank line

    fmt.Println(env["DATABASE_PWD"]) // Outputs "foo"

}

这将不起作用,因为变量在init运行之前已初始化;这是按照规范

一个没有导入的包是通过为它的所有包级变量分配初始值,然后按照它们在源代码中出现的顺序调用所有 init 函数来初始化的,可能在多个文件中,如呈现给编译器。如果一个包有导入,导入的包在初始化包本身之前被初始化......

所以 的值是在运行password之前设置的(这意味着密码将是您启动应用程序时环境中的任何值 - 可能为空)。godotenv.Load()

您可以通过在运行后加载环境变量来解决此问题godotenv.Load()。我建议这样做,main以便您可以处理任何错误(godotenv.Load()可能会失败!)。请参阅包 repo 中的示例

注意:这就是为什么包含一个最小的、可重现的示例很重要的原因。创建这样的示例时,您可能会注意到它password是空的,并且问题与database/sql. 如果没有比问题中提供的更多信息,则无法回答该问题。


查看完整回答
反对 回复 2023-02-21
?
炎炎设计

TA贡献1808条经验 获得超4个赞

为什么您的解决方案无法按预期工作

我想你误解了 os.GetEnv() 函数的作用,你的操作系统有一些叫做环境变量的东西,这就是你想要达到的目的。

您的代码返回一个空字符串,因为它未设置为环境变量。

您可以查看以下位置以了解有关此功能及其工作原理的更多信息:

你想做什么

现在请允许我解释一下您想实际做什么,您想从文件中获取这些变量,因此您需要:

  • 告诉程序它在哪里

  • 打开它

  • 解析它

  • 读取值

您可以通过两种方式做到这一点。

第一个解决方案(自己动手)

首先打开文件并将其内容传递给扫描仪。然后,您遍历每一行并使用“=”字符(Env 格式)将该行分成两部分,最后将其键/值存储在地图之类的东西中(或您想要/需要的任何东西)。

第二个解决方案(对于懒惰的开发或复杂的项目)

第二,如果你不想做所有这些,只需使用配置库或解析器为你做。

这是使用 Viper 执行此操作的链接: Load config from file & environment variables in Golang with Viper


查看完整回答
反对 回复 2023-02-21
  • 2 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信