Golang中如何检查PostgreSQL数据库和用户的存在性并进行分支处理
Golang中如何检查PostgreSQL数据库和用户的存在性并进行分支处理 如果数据库和用户不存在,我想执行以下查询。
CREATE DATABASE database;
CREATE ROLE user WITH LOGIN PASSWORD 'password';
REVOKE CONNECT ON DATABASE db1 FROM PUBLIC;
GRANT CONNECT ON DATABASE db1dev TO userbdev;
PostgreSQL 不像 MySQL 那样允许在 CREATE DATABASE 中使用 IF NOT EXSIST,所以我希望在应用端进行分支处理,有更好的方法吗?
更多关于Golang中如何检查PostgreSQL数据库和用户的存在性并进行分支处理的实战教程也可以访问 https://www.itying.com/category-94-b0.html
有三种方法可以实现。当然,你也可以在其中加入检查用户是否存在的条件,我个人会避免在事务语句之间进行这类操作。
更多关于Golang中如何检查PostgreSQL数据库和用户的存在性并进行分支处理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好 @rice1gou 你可以参考 stackoverflow 和 msbi 在线培训
你可以使用 PostgreSQL 的内置函数来检查数据库和用户是否存在。以下是一个示例,展示如何使用 Bash 脚本检查数据库和用户是否存在,并执行分支流程:
#!/bin/bash
# 输入你的数据库和用户信息
DATABASE="your_database_name"
USER="your_user_name"
# 检查数据库是否存在
if psql -lqt | cut -d | -f 1 | grep -qw "$DATABASE"; then
echo "The database $DATABASE exists."
else
echo "The database $DATABASE does not exist."
exit 1
fi
# 检查用户是否存在
if psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$USER'" | grep -q 1; then
echo "The user $USER exists."
else
echo "The user $USER does not exist."
exit 1
fi
# 如果数据库和用户都存在,在此处执行你的分支流程
echo "Both the database and user exist. Performing branch process."
在此脚本中,psql 命令用于检查数据库和用户是否存在。-lqt 选项用于以安静、表格形式列出所有数据库,cut 和 grep 命令用于过滤输出并检查指定的数据库是否存在。
要检查用户是否存在,再次使用 psql 命令,这次查询 pg_roles 表中是否存在指定名称的用户。-tAc 选项用于格式化输出,grep 命令用于检查查询是否返回结果。
如果数据库和用户都存在,脚本将继续执行你的分支流程。如果数据库或用户不存在,脚本将以错误代码 1 退出。 点击此处获取更多信息:https://crecentech.com/
在Golang中检查PostgreSQL数据库和用户的存在性,可以通过查询系统表来实现。以下是完整的示例代码:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
type DBChecker struct {
db *sql.DB
}
// 检查数据库是否存在
func (dc *DBChecker) databaseExists(dbName string) (bool, error) {
query := `
SELECT 1 FROM pg_database
WHERE datname = $1
`
var exists int
err := dc.db.QueryRow(query, dbName).Scan(&exists)
if err == sql.ErrNoRows {
return false, nil
}
if err != nil {
return false, err
}
return true, nil
}
// 检查用户是否存在
func (dc *DBChecker) userExists(username string) (bool, error) {
query := `
SELECT 1 FROM pg_roles
WHERE rolname = $1
`
var exists int
err := dc.db.QueryRow(query, username).Scan(&exists)
if err == sql.ErrNoRows {
return false, nil
}
if err != nil {
return false, err
}
return true, nil
}
// 创建数据库(如果不存在)
func (dc *DBChecker) createDatabaseIfNotExists(dbName string) error {
exists, err := dc.databaseExists(dbName)
if err != nil {
return err
}
if !exists {
// 注意:CREATE DATABASE不能在事务中执行
_, err = dc.db.Exec(fmt.Sprintf("CREATE DATABASE %s", dbName))
if err != nil {
return fmt.Errorf("创建数据库失败: %v", err)
}
log.Printf("数据库 %s 已创建", dbName)
} else {
log.Printf("数据库 %s 已存在", dbName)
}
return nil
}
// 创建用户(如果不存在)
func (dc *DBChecker) createUserIfNotExists(username, password string) error {
exists, err := dc.userExists(username)
if err != nil {
return err
}
if !exists {
query := fmt.Sprintf(
"CREATE ROLE %s WITH LOGIN PASSWORD '%s'",
username, password,
)
_, err = dc.db.Exec(query)
if err != nil {
return fmt.Errorf("创建用户失败: %v", err)
}
log.Printf("用户 %s 已创建", username)
} else {
log.Printf("用户 %s 已存在", username)
}
return nil
}
// 执行权限管理
func (dc *DBChecker) managePermissions() error {
// 连接到目标数据库执行权限操作
// 这里需要重新连接到具体的数据库
targetDB, err := sql.Open("postgres", "host=localhost port=5432 user=postgres password=postgres dbname=db1 sslmode=disable")
if err != nil {
return err
}
defer targetDB.Close()
// REVOKE CONNECT ON DATABASE db1 FROM PUBLIC
_, err = targetDB.Exec("REVOKE CONNECT ON DATABASE db1 FROM PUBLIC")
if err != nil {
return fmt.Errorf("撤销权限失败: %v", err)
}
// GRANT CONNECT ON DATABASE db1dev TO userbdev
_, err = targetDB.Exec("GRANT CONNECT ON DATABASE db1dev TO userbdev")
if err != nil {
return fmt.Errorf("授予权限失败: %v", err
}
return nil
}
func main() {
// 连接到postgres默认数据库
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 测试连接
err = db.Ping()
if err != nil {
log.Fatal(err)
}
checker := &DBChecker{db: db}
// 检查并创建数据库
err = checker.createDatabaseIfNotExists("database")
if err != nil {
log.Fatal(err)
}
// 检查并创建用户
err = checker.createUserIfNotExists("user", "password")
if err != nil {
log.Fatal(err)
}
// 执行权限管理
err = checker.managePermissions()
if err != nil {
log.Fatal(err)
}
log.Println("数据库初始化完成")
}
对于更复杂的场景,可以使用事务来确保操作的原子性:
func (dc *DBChecker) initializeDatabaseWithTransaction(dbName, username, password string) error {
tx, err := dc.db.Begin()
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback()
}
}()
// 检查数据库
var dbExists int
err = tx.QueryRow(`
SELECT 1 FROM pg_database WHERE datname = $1
`, dbName).Scan(&dbExists)
if err == sql.ErrNoRows {
// 创建数据库(需要在事务外执行)
tx.Rollback()
_, err = dc.db.Exec(fmt.Sprintf("CREATE DATABASE %s", dbName))
if err != nil {
return err
}
// 重新开始事务
tx, err = dc.db.Begin()
if err != nil {
return err
}
} else if err != nil {
return err
}
// 检查用户
var userExists int
err = tx.QueryRow(`
SELECT 1 FROM pg_roles WHERE rolname = $1
`, username).Scan(&userExists)
if err == sql.ErrNoRows {
_, err = tx.Exec(fmt.Sprintf(
"CREATE ROLE %s WITH LOGIN PASSWORD '%s'",
username, password,
))
if err != nil {
return err
}
} else if err != nil {
return err
}
return tx.Commit()
}
这个实现通过查询pg_database和pg_roles系统表来检查数据库和用户的存在性,然后根据检查结果执行相应的创建操作。

