无法连接到 psql 数据库

huangapple go评论124阅读模式
英文:

Unable to connect to psql db

问题

我正在尝试连接到数据库,但是当我使用GET方法向端点发出curl请求时,出现错误。我已经仔细检查了用户凭据,并授予了完全权限和超级用户权限。
以下是当curl端点时我收到的错误:

  1. santosh@pkg*$:curl -i localhost:8080/books/show
  2. HTTP/1.1 303 See Other
  3. Content-Type: text/html; charset=utf-8
  4. Location: /books
  5. Date: Sat, 19 Nov 2022 12:09:52 GMT
  6. Content-Length: 33
  7. <a href="/books">See Other</a>.

当与数据库建立连接时,当向数据库发出请求时,会触发以下错误:

  1. santosh@pkg*$:go run main.go
  2. Database connection successful.
  3. 2022/11/19 17:39:47 http: panic serving 127.0.0.1:44324: runtime error: invalid memory address or nil pointer dereference
  4. goroutine 35 [running]:
  5. net/http.(*conn).serve.func1()
  6. /usr/local/go/src/net/http/server.go:1850 +0xbf
  7. panic({0x6960e0, 0x8e5630})
  8. /usr/local/go/src/runtime/panic.go:890 +0x262
  9. database/sql.(*DB).conn(0x0, {0x7593d0, 0xc00011a000}, 0x1)
  10. /usr/local/go/src/database/sql/sql.go:1288 +0x53
  11. database/sql.(*DB).query(0x6?, {0x7593d0, 0xc00011a000}, {0x6da967, 0x13}, {0x0, 0x0, 0x0}, 0x68?)

主程序:

  1. var db *sql.DB
  2. type Books struct {
  3. Isbn string
  4. Title string
  5. Author string
  6. Price float32
  7. }
  8. func init() {
  9. var err error
  10. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  11. db, err := sql.Open("postgres", args)
  12. if err != nil {
  13. fmt.Printf("Creating Database %s", err)
  14. }
  15. if err = db.Ping(); err != nil {
  16. panic(err)
  17. }
  18. fmt.Println("Database connection succussful.")
  19. }
  20. func main() {
  21. http.HandleFunc("/", index)
  22. http.HandleFunc("/books", booksIndex)
  23. http.ListenAndServe(":8080", nil)
  24. }
  25. func index(w http.ResponseWriter, r *http.Request) {
  26. http.Redirect(w, r, "/books", http.StatusSeeOther)
  27. }
  28. func booksIndex(w http.ResponseWriter, r *http.Request) {
  29. if r.Method != "GET" {
  30. http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
  31. return
  32. }
  33. rows, err := db.Query("SELECT * FROM books")
  34. if err != nil {
  35. http.Error(w, http.StatusText(500), 500)
  36. return
  37. }
  38. defer rows.Close()
  39. bks := make([]Books, 0)
  40. for rows.Next() {
  41. bk := Books{}
  42. err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
  43. if err != nil {
  44. http.Error(w, http.StatusText(500), 500)
  45. return
  46. }
  47. bks = append(bks, bk)
  48. }
  49. if err = rows.Err(); err != nil {
  50. http.Error(w, http.StatusText(500), 500)
  51. return
  52. }
  53. }

我尝试了多次检查用户权限、数据库格式和顺序,所有内容都与代码一致。连接已经建立,但在查询数据库时出现了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:

  1. santosh@pkg*$:curl -i localhost:8080/books/show
  2. HTTP/1.1 303 See Other
  3. Content-Type: text/html; charset=utf-8
  4. Location: /books
  5. Date: Sat, 19 Nov 2022 12:09:52 GMT
  6. Content-Length: 33
  7. <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:

  1. santosh@pkg*$:go run main.go
  2. Database connection successful.
  3. 2022/11/19 17:39:47 http: panic serving 127.0.0.1:44324: runtime error: invalid memory address or nil pointer dereference
  4. goroutine 35 [running]:
  5. net/http.(*conn).serve.func1()
  6. /usr/local/go/src/net/http/server.go:1850 +0xbf
  7. panic({0x6960e0, 0x8e5630})
  8. /usr/local/go/src/runtime/panic.go:890 +0x262
  9. database/sql.(*DB).conn(0x0, {0x7593d0, 0xc00011a000}, 0x1)
  10. /usr/local/go/src/database/sql/sql.go:1288 +0x53
  11. database/sql.(*DB).query(0x6?, {0x7593d0, 0xc00011a000}, {0x6da967, 0x13}, {0x0, 0x0, 0x0}, 0x68?)

The main program:

  1. var db *sql.DB
  2. type Books struct {
  3. Isbn string
  4. Title string
  5. Author string
  6. Price float32
  7. }
  8. func init() {
  9. var err error
  10. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  11. db, err := sql.Open("postgres", args)
  12. if err != nil {
  13. fmt.Printf("Creating Database %s", err)
  14. }
  15. if err = db.Ping(); err != nil {
  16. panic(err)
  17. }
  18. fmt.Println("Database connection succussful.")
  19. }
  20. func main() {
  21. http.HandleFunc("/", index)
  22. http.HandleFunc("/books", booksIndex)
  23. http.ListenAndServe(":8080", nil)
  24. }
  25. func index(w http.ResponseWriter, r *http.Request) {
  26. http.Redirect(w, r, "/books", http.StatusSeeOther)
  27. }
  28. func booksIndex(w http.ResponseWriter, r *http.Request) {
  29. if r.Method != "GET" {
  30. http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
  31. return
  32. }
  33. rows, err := db.Query("SELECT * FROM books")
  34. if err != nil {
  35. http.Error(w, http.StatusText(500), 500)
  36. return
  37. }
  38. defer rows.Close()
  39. bks := make([]Books, 0)
  40. for rows.Next() {
  41. bk := Books{}
  42. err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price)
  43. if err != nil {
  44. http.Error(w, http.StatusText(500), 500)
  45. return
  46. }
  47. bks = append(bks, bk)
  48. }
  49. if err = rows.Err(); err != nil {
  50. http.Error(w, http.StatusText(500), 500)
  51. return
  52. }
  53. }

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变量。

:=运算符被称为“短变量声明”,它在其块作用域中声明并初始化一个新的变量。任何外部作用域中具有相同名称的变量将被“遮蔽”。

要正确初始化包级别的变量,你可以使用普通的赋值

  1. var db *sql.DB
  2. func init() {
  3. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  4. var err error
  5. db, err = sql.Open("postgres", args)
  6. if err != nil {
  7. fmt.Printf("Creating Database %s", err)
  8. }
  9. // ...
  10. }

或者你可以使用:=,但是使用不同的变量名,并确保在赋值时使用该变量名:

  1. var db *sql.DB
  2. func init() {
  3. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  4. _db, err := sql.Open("postgres", args)
  5. if err != nil {
  6. fmt.Printf("Creating Database %s", err)
  7. }
  8. // ...
  9. db = _db // 设置“全局”变量
  10. }
英文:

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:

  1. var db *sql.DB
  2. func init() {
  3. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  4. var err error
  5. db, err = sql.Open("postgres", args)
  6. if err != nil {
  7. fmt.Printf("Creating Database %s", err)
  8. }
  9. // ...
  10. }

Or you can use := but then use a different variable name and make sure to use that for the assignment:

  1. var db *sql.DB
  2. func init() {
  3. args := fmt.Sprintf("host=%s port=%d dbname=%s user='%s' password=%s sslmode=%s", "localhost", 5432, "bookstore", "santosh", "dts123", "disable")
  4. _db, err := sql.Open("postgres", args)
  5. if err != nil {
  6. fmt.Printf("Creating Database %s", err)
  7. }
  8. // ...
  9. db = _db // set "global"
  10. }

huangapple
  • 本文由 发表于 2022年11月19日 21:50:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/74500597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定