Golang中POSTGRES报错:pq relation does not exist的解决方法

Golang中POSTGRES报错:pq relation does not exist的解决方法 我正在尝试向一个我知道存在的表中插入数据,因为完全相同的查询直接在数据库中可以正常工作。

GO代码:

const (
host     = "localhost"
user     = "postgres"
password = "postgres"
dbname   = "user_details"
)

func connectDb() *sql.DB {
sqlInfo := fmt.Sprintf("host=%s user=%s "+
	"password=%s dbname=%s sslmode=disable",
	host, user, password, dbname)

db, err := sql.Open("postgres", sqlInfo)

fmt.Fprintf(os.Stdout, "\n%v", sqlInfo)

if err != nil {
	panic(err)
}

err = db.Ping()

if err != nil {
	panic(err)
}

fmt.Fprintf(os.Stdout, "You have successfully connected to the database")
return db
} 

上面的代码创建了连接,我在主函数中调用 db = connectDb,将全局 db 变量设置为从 connectDB 函数返回的数据库。这似乎可以正常工作,并且使用内置的 ping 方法连接正常。

下面的代码是从 handleRegister 函数运行的插入语句。我已经做了检查来确保数据库仍然连接,它应该是连接的,因为我在主函数中有一个 defer db.Close(),在程序退出时关闭数据库连接。

	sqlSt := `INSERT INTO users ("User_id",  "username", "password", "email", "gender", "gang") VALUES ($1, $2, $3, $4, $5, $6)`
_, err = db.Exec(sqlSt, 1, ud.Username, pw, ud.Email, ud.Gender, ud.Gang)
if err != nil {
	panic(err)
}

下面是我数据库中的表。

Screenshot%20from%202019-02-07%2018-39-58

任何帮助都将不胜感激

最小程序:

错误:查询数据库失败,panic: pq: relation “users” 不存在

package main

import (
"database/sql"
"fmt"
"os"

_ "github.com/lib/pq"
)

const (
host     = "localhost"
user     = "postgres"
password = "postgres"
dbname   = "user_details"
)

func main() {
sqlInfo := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", host, user, password, dbname)

db, err := sql.Open("postgres", sqlInfo)

if err != nil {
	fmt.Fprintf(os.Stdout, "Connection to the database failed")
	return
}
err = db.Ping()

if err != nil {
	fmt.Fprintf(os.Stdout, "Connection to the database failed")
	return
}

fmt.Fprintf(os.Stdout, "You have connected to the database successfully")

sqlQuery := `INSERT INTO users ("user_id", "username", "password", "email", "gender", "gang") VALUES ($1, $2, $3, $4, $5, $6)`
_, err = db.Exec(sqlQuery, 1, "Ross8839", "rocky8839", "ross88399@hotmail.com", "Female", "Greengos")
if err != nil {
	fmt.Fprintf(os.Stdout, "Failed to query db")
	panic(err)
}
}

更多关于Golang中POSTGRES报错:pq relation does not exist的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

有任何错误吗?

更多关于Golang中POSTGRES报错:pq relation does not exist的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


如果您同时指定模式是否有效:

sqlQuery := "INSERT INTO user_details.users ....

你能显示 describe users 的输出吗?

我已经用最简化的程序更新了这个帖子,它输出了完全相同的错误。

user_details 是数据库的名称,而不是模式的名称。模式默认为 public。因此我怀疑这能解决问题。

是的……错误是 PQ(Postgres)关系不存在……基本上是在告诉我“users”表不存在。

编写最精简的程序并进行测试。类似这样的示例:https://goplay.space/#pcrciTaNPXW 如果这仍无法运行,问题可能出在与数据库的接口交互上。若这段代码出现在多个位置,也可能是其他原因所致。细节决定成败。

这个错误通常是因为表名在SQL查询中使用了错误的大小写或模式。PostgreSQL默认将未加引号的标识符转换为小写,但使用双引号时区分大小写。

在你的代码中,表名在SQL语句中使用了双引号:"users"。如果表在数据库中实际是以小写形式存在的,这应该可以工作。但问题可能出现在以下几个方面:

  1. 表可能在不同的模式(schema)中,而不是在默认的public模式
  2. 表名可能有不同的大小写形式
  3. 连接可能指向了不同的数据库

以下是几种解决方案:

方案1:检查表所在的模式

// 明确指定模式
sqlQuery := `INSERT INTO public.users ("user_id", "username", "password", "email", "gender", "gang") VALUES ($1, $2, $3, $4, $5, $6)`

方案2:不使用双引号的表名

// PostgreSQL会将未加引号的标识符转换为小写
sqlQuery := `INSERT INTO users (user_id, username, password, email, gender, gang) VALUES ($1, $2, $3, $4, $5, $6)`

方案3:添加调试代码检查表是否存在

// 在执行插入前先检查表是否存在
func checkTableExists(db *sql.DB, tableName string) bool {
    var exists bool
    query := `SELECT EXISTS (
        SELECT FROM information_schema.tables 
        WHERE table_schema = 'public' 
        AND table_name = $1
    )`
    err := db.QueryRow(query, tableName).Scan(&exists)
    if err != nil {
        panic(err)
    }
    return exists
}

// 在main函数中使用
if !checkTableExists(db, "users") {
    fmt.Fprintf(os.Stdout, "Table 'users' does not exist in public schema")
    return
}

方案4:列出所有可用的表

func listTables(db *sql.DB) {
    rows, err := db.Query(`
        SELECT table_schema, table_name 
        FROM information_schema.tables 
        WHERE table_schema NOT IN ('information_schema', 'pg_catalog')
        ORDER BY table_schema, table_name
    `)
    if err != nil {
        panic(err)
    }
    defer rows.Close()
    
    for rows.Next() {
        var schema, table string
        if err := rows.Scan(&schema, &table); err != nil {
            panic(err)
        }
        fmt.Printf("Schema: %s, Table: %s\n", schema, table)
    }
}

// 在连接后调用
listTables(db)

建议先使用方案4来确认表的确切名称和所在模式,然后相应地调整SQL查询。

回到顶部