在 Go 中使用 Gorm 连接到 PostgreSQL 时,我的应用程序连接到默认的
postgres
数据库,而不是我配置的特定数据库。
func (app *Application) ConnectToPostgres() error {
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=UTC",
app.Config.DB.Host,
app.Config.DB.User,
app.Config.DB.Password,
app.Config.DB.DBName,
app.Config.DB.Port,
)
// Despite dsn specifying 'my_database_name', connection uses 'postgres'
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return err
}
app.DB = db
return nil
}
.env
文件:
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=
DB_NAME=my_database_name
my_database_name
存在为什么 Gorm 可能会忽略指定的数据库名称?
这是我的主文件
package main
import (
"flag"
"log"
"os"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
"github.com/lordaris/aris-erp/api"
)
func main() {
r := gin.Default()
// Load environment variables from .env file
err := godotenv.Load(".env")
if err != nil {
log.Fatal("Error loading .env file")
}
var cfg api.Config
flag.StringVar(&cfg.DB.Host, "db-host", os.Getenv("DB_HOST"), "PostgreSQL host")
flag.StringVar(&cfg.DB.Port, "db-port", os.Getenv("DB_PORT"), "PostgreSQL port")
flag.StringVar(&cfg.DB.User, "db-user", os.Getenv("DB_USER"), "PostgreSQL user")
flag.StringVar(&cfg.DB.Password, "db-password", os.Getenv("DB_PASSWORD"), "PostgreSQL password")
flag.StringVar(&cfg.DB.DBName, "db-name", os.Getenv("DB_NAME"), "PostgreSQL database name")
flag.Parse()
app := api.NewApplication(cfg)
// Connect to PostgreSQL
if err := app.ConnectToPostgres(); err != nil {
log.Fatal("Could not connect to PostgreSQL: ", err)
}
// Router
api.Router(r, app)
r.Run()
}
我在修改数据库连接的用户名时遇到问题。该错误表明以用户名作为名称的数据库不存在,这是有道理的。然而,这让我发现真正的问题是我的连接字符串中缺少密码。这导致后续变量移位,空密码被解释为数据库名称。
为了解决此问题,我从连接字符串中完全删除了密码占位符。或者,我可以使用实际密码,但现在我决定不包含密码。
我认为出现此问题是因为数据源名称 (DSN) 中的
password
字段为空。在 PostgreSQL 连接字符串中,如果省略 password
或留空,则可能无法正确解释后续参数,从而导致意外行为。在您的情况下,空 password
字段会导致 dbname
参数被误解,从而导致连接到默认 postgres
数据库,而不是您想要的 my_database_name
。
试试这个:
if password == "" {
password = "''" // Use empty single quotes to represent an empty password
}