This works perfectly and the database is connected, no problems. But I do not want to hardcode my values in the function and hence am using an env file. But using os.getenv doesn’t connect to the database.
package main
import (
"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.")
}
The following code gives the error- panic: pq: password authentication failed for user "bond"
var (
host = "localhost"
port = 5432
user = "bond"
password = os.Getenv("DATABASE_PWD")
dbname = "bookstore"
)
Why does this happen?
2
Answers
Why your solution does not work as intended
I think you misunderstood what the os.GetEnv() function does, your operating system has got something that is called environment variables and that is what you are trying to get here.
Your code returns either an empty string because it is not set as an Environment variable.
You can look at the following places to learn a bit more about this function and how it works:
What you want to do
Now allow me to explain what you want to actually do, you want to get these variables from a file, so you need to:
You can do that in two ways.
First solution (Do it Yourself)
First you open the file and pass its content to a scanner.
You then iterate over each line and split the line in two using the ‘=’ character (Env format), finally store its key/value in something like a map (or whatever you want/need it to be).
Second solution (for the lazy dev or complex project)
The second, if you don’t want to do all of this, just use a config library or parser do it for you.
Here is a link to do it using Viper:
Load config from file & environment variables in Golang with Viper
It appears that you are doing something like this (playground):
This will not work because the variables are initialized before
init
is run; this is as per the spec:So the value of
password
is set beforegodotenv.Load()
is run (meaning the password will be whatever value was in the environment when you started the app – probably empty).You can fix this by loading environmental variables after you have run
godotenv.Load()
. I would suggest doing this inmain
so that you can handle any errors (godotenv.Load()
may fail!). See the example in the package repo.Note: This is why it’s important to include a minimal, reproducible, example. When creating such an example you would probably have noticed that
password
was empty and that the issue was not at all related todatabase/sql
. The question could not be answered without more info than provided in the question.