Gorm/PostgreSQL:如何确保连接到特定数据库而不是默认数据库

问题描述 投票:0回答:1

在 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
    存在
  • 连接字符串包含正确的数据库名称
  • 打印时 DSN 格式正确
  • 可通过 psql 访问数据库

为什么 Gorm 可能会忽略指定的数据库名称?

其他背景

  • Go版本:1.23.3
  • Gorm版本:12.25.12
  • PostgreSQL 版本:16.3
  • 操作系统:Arch Linux

更多背景

这是我的主文件

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()
}

最后编辑:

我在修改数据库连接的用户名时遇到问题。该错误表明以用户名作为名称的数据库不存在,这是有道理的。然而,这让我发现真正的问题是我的连接字符串中缺少密码。这导致后续变量移位,空密码被解释为数据库名称。

为了解决此问题,我从连接字符串中完全删除了密码占位符。或者,我可以使用实际密码,但现在我决定不包含密码。

postgresql go go-gorm
1个回答
0
投票

我认为出现此问题是因为数据源名称 (DSN) 中的

password
字段为空。在 PostgreSQL 连接字符串中,如果省略
password
或留空,则可能无法正确解释后续参数,从而导致意外行为。在您的情况下,空
password
字段会导致
dbname
参数被误解,从而导致连接到默认
postgres
数据库,而不是您想要的
my_database_name

试试这个:

 if password == "" {
        password = "''" // Use empty single quotes to represent an empty password
    }
© www.soinside.com 2019 - 2024. All rights reserved.