如何使用GORM创建Postgres数据库

xfb7svmp  于 2023-05-04  发布在  Go
关注(0)|答案(5)|浏览(289)

这主要集中在为我计划编写的涉及创建数据库的测试套件提供setup()和teardown()方法。
我已经弄明白了如何使用GORM创建一个DB。但是,我不确定这是否是最好的方法。

package main

import (
    "fmt"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/postgres"
    "log"
)

func main() {
    db, err := gorm.Open("postgres", "host=127.0.0.1 port=5432 user=superuser dbname=postgres password='' sslmode=disable")
    capture(err)
    db = db.Exec("CREATE DATABASE test_db;")
    if db.Error != nil {
        fmt.Println("Unable to create DB test_db, attempting to connect assuming it exists...")
        db, err = gorm.Open("postgres", "host=127.0.0.1 port=5432 user=superuser dbname=test_db password='' sslmode=disable")
        if err != nil {
           fmt.Println("Unable to connect to test_db")
           capture(err)
        }
    }
    defer db.Close()
}

func capture(err error) {
    if err != nil {
        log.Fatalf("%s", err)
   }
}

我首先连接到默认的postgres数据库,然后创建第二个测试数据库,并计划使用它。
这是最好的方法吗?或者有没有一种方法可以连接到Postgres而不需要预先存在的DB。

  • 注意 *:我已经查找了人们使用SQL驱动程序仅使用连接字符串user:password@/连接到数据库的答案。这在我的情况下不起作用。(像here

我也尝试过没有数据库名称的连接字符串,这导致驱动程序试图连接到与用户同名的数据库。这失败了,因为这样的DB不存在。

zpqajqem

zpqajqem1#

我的方法是避免在创建数据库时,首先期望出现错误,然后将其用作db已经存在的指示。我觉得下面更优雅的IMO。这是使用GORM顺便说一句

connStr := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=disable",
    "user",
    "password",
    "host",
    "port",
    "postgres")

// connect to the postgres db just to be able to run the create db statement
db, err := gorm.Open(postgres.Open(connStr), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Silent)})
if err != nil {
    return err
}

// check if db exists
stmt := fmt.Sprintf("SELECT * FROM pg_database WHERE datname = '%s';", client.Name)
rs := db.Raw(stmt)
if rs.Error != nil {
    return rs.Error
}

// if not create it
var rec = make(map[string]interface{})
if rs.Find(rec); len(rec) == 0 {
    stmt := fmt.Sprintf("CREATE DATABASE %s;", dbName)
    if rs := db.Exec(stmt); rs.Error != nil {
        return rs.Error
    }

    // close db connection
    sql, err := db.DB()
    defer func() {
        _ = sql.Close()
    }()
    if err != nil {
        return err
    }
}
fcg9iug3

fcg9iug32#

下面是我如何使用Gorm创建一个PostgreSQL数据库,关键是只连接到PostgreSQL,创建数据库不需要连接到“数据库”,只连接到数据库引擎就足够了。只是不要在连接字符串中传递数据库。
在主区,快去

package main

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "fmt"
    "github.com/joho/godotenv"
)

func createDatabase() {
    dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable TimeZone=%s", Config("DB_HOST"), Config("DB_PORT"), Config("DB_USER"), Config("DB_PASSWORD"), Config("DB_TIMEZONE"))
    DB, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{})

    createDatabaseCommand := fmt.Sprintf("CREATE DATABASE %s", Config("DB_NAME"))
    DB.Exec(createDatabaseCommand)
}
 
func main() {
    createDatabase()
}

现在只需运行go get -d ./... && go run main.go

vmpqdwk3

vmpqdwk33#

你的方法似乎很有效。您还可以使用postgres的createdb实用程序在连接到数据库之前创建数据库。例如:

import (
    "log"
    "os/exec"
    "bytes"
)

func createPgDb() {
    cmd := exec.Command("createdb", "-p", "5432", "-h", "127.0.0.1", "-U", "superuser", "-e", "test_db")
    var out bytes.Buffer
    cmd.Stdout = &out
    if err := cmd.Run(); err != nil {
        log.Printf("Error: %v", err)
    }
    log.Printf("Output: %q\n", out.String())
}

这个例子是从Go手册www.example.com中的命令/运行例子中改写https://golang.org/pkg/os/exec/#Command

jvidinwx

jvidinwx4#

我建议使用database/psql包来创建数据库,而不是gorm
请确保导入了这些包

import (
    "database/sql"
    "fmt"
    _ "github.com/lib/pq"
)

并使用下面的代码来创建数据库

url := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable",
        DBHost, DBPort, DBUsername, DBPassword)
db, err := sql.Open("postgres", url)
if err != nil {
    panic(err)
}
defer db.Close()

_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", DBName))
if err != nil {
    panic(err)
}
rkkpypqq

rkkpypqq5#

这是我的目标

var DB * gorm.DB

func ConnectToDb(params *types.AppParameters) {
    var err error
    dbName := os.Getenv("DB_NAME")
    conn_url := fmt.Sprintf("user=%s password=%s host=%s port=%s sslmode=disable",
        os.Getenv("DB_USER"),
        os.Getenv("DB_PASSWORD"),
        os.Getenv("DB_HOST"),
        os.Getenv("DB_PORT"),
    )
    conn_db_url := fmt.Sprintf("%s dbname=%s", conn_url, dbName)
    DB, err = gorm.Open(postgres.Open(conn_url), &gorm.Config{})
    count  := 0
    DB.Raw("SELECT count(*) FROM pg_database WHERE datname = ?", dbName).Scan(&count)
    if count == 0 {
        sql :=fmt.Sprintf("CREATE DATABASE %s", dbName)
        result := DB.Exec(sql)
        utils.CheckError(result.Error)
    }

    DB, err = gorm.Open(postgres.Open(conn_db_url), &gorm.Config{})
    utils.CheckError(err)
    
}

相关问题