英文:
Unable to connect to psql db
问题
我正在尝试连接到数据库,但是当我使用GET
方法向端点发出curl请求时,出现错误。我已经仔细检查了用户凭据,并授予了完全权限和超级用户权限。
以下是当curl端点时我收到的错误:
santosh@pkg*$:curl -i localhost:8080/books/show
HTTP/1.1 303 See Other
Content-Type: text/html; charset=utf-8
Location: /books
Date: Sat, 19 Nov 2022 12:09:52 GMT
Content-Length: 33
<a href="/books">See Other</a>.
当与数据库建立连接时,当向数据库发出请求时,会触发以下错误:
santosh@pkg*$:go run main.go
Database connection successful.
2022/11/19 17:39:47 http: panic serving 127.0.0.1:44324: runtime error: invalid memory address or nil pointer dereference
goroutine 35 [running]:
net/http.(*conn).serve.func1()
/usr/local/go/src/net/http/server.go:1850 +0xbf
panic({0x6960e0, 0x8e5630})
/usr/local/go/src/runtime/panic.go:890 +0x262
database/sql.(*DB).conn(0x0, {0x7593d0, 0xc00011a000}, 0x1)
/usr/local/go/src/database/sql/sql.go:1288 +0x53
database/sql.(*DB).query(0x6?, {0x7593d0, 0xc00011a000}, {0x6da967, 0x13}, {0x0, 0x0, 0x0}, 0x68?)
主程序:
var db *sql.DB
type Books struct {
Isbn string
Title string
Author string
Price float32
}
func init() {
var err error
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
db, err := sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
if err = db.Ping(); err != nil {
panic(err)
}
fmt.Println("Database connection succussful.")
}
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/books", booksIndex)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/books", http.StatusSeeOther)
}
func booksIndex(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
return
}
rows, err := db.Query("SELECT * FROM books")
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
defer rows.Close()
bks := make([]Books, 0)
for rows.Next() {
bk := Books{}
err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
bks = append(bks, bk)
}
if err = rows.Err(); err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
}
我尝试了多次检查用户权限、数据库格式和顺序,所有内容都与代码一致。连接已经建立,但在查询数据库时出现了panic错误。
英文:
I am trying to connect to a database, but getting an error when I make a curl request to the endpoint with the GET
method. I double-checked with the user credentials and have granted full privileges and superuser permissions.
Following is the error I get when curl the endpoint:
santosh@pkg*$:curl -i localhost:8080/books/show
HTTP/1.1 303 See Other
Content-Type: text/html; charset=utf-8
Location: /books
Date: Sat, 19 Nov 2022 12:09:52 GMT
Content-Length: 33
<a href="/books">See Other</a>.
The connection is established with the Database, when the request is made to the database these errors are triggered:
santosh@pkg*$:go run main.go
Database connection successful.
2022/11/19 17:39:47 http: panic serving 127.0.0.1:44324: runtime error: invalid memory address or nil pointer dereference
goroutine 35 [running]:
net/http.(*conn).serve.func1()
/usr/local/go/src/net/http/server.go:1850 +0xbf
panic({0x6960e0, 0x8e5630})
/usr/local/go/src/runtime/panic.go:890 +0x262
database/sql.(*DB).conn(0x0, {0x7593d0, 0xc00011a000}, 0x1)
/usr/local/go/src/database/sql/sql.go:1288 +0x53
database/sql.(*DB).query(0x6?, {0x7593d0, 0xc00011a000}, {0x6da967, 0x13}, {0x0, 0x0, 0x0}, 0x68?)
The main program:
var db *sql.DB
type Books struct {
Isbn string
Title string
Author string
Price float32
}
func init() {
var err error
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
db, err := sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
if err = db.Ping(); err != nil {
panic(err)
}
fmt.Println("Database connection succussful.")
}
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/books", booksIndex)
http.ListenAndServe(":8080", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/books", http.StatusSeeOther)
}
func booksIndex(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
return
}
rows, err := db.Query("SELECT * FROM books")
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
defer rows.Close()
bks := make([]Books, 0)
for rows.Next() {
bk := Books{}
err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
bks = append(bks, bk)
}
if err = rows.Err(); err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
}
I tried double-checking user privileges and database format and for order. All are in line with the code. The connection is established but fails with panic while querying the DB.
答案1
得分: 0
你没有正确初始化包级别的db
变量。
:=
运算符被称为“短变量声明”,它在其块作用域中声明并初始化一个新的变量。任何外部作用域中具有相同名称的变量将被“遮蔽”。
要正确初始化包级别的变量,你可以使用普通的赋值:
var db *sql.DB
func init() {
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
var err error
db, err = sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
// ...
}
或者你可以使用:=
,但是使用不同的变量名,并确保在赋值时使用该变量名:
var db *sql.DB
func init() {
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
_db, err := sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
// ...
db = _db // 设置“全局”变量
}
英文:
You are not properly initializing the package-level db
variable.
The :=
operator, called "short variable declaration", declares and initializes a new variable in its block scope. Any variable with the same name in an outer scope will be "shadowed".
To properly initialize the package-level variable you can use plain assignment:
var db *sql.DB
func init() {
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
var err error
db, err = sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
// ...
}
Or you can use :=
but then use a different variable name and make sure to use that for the assignment:
var db *sql.DB
func init() {
args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
_db, err := sql.Open("postgres", args)
if err != nil {
fmt.Printf("Creating Database %s", err)
}
// ...
db = _db // set "global"
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论