使用Go/Echo+PostgreSQL开发REST API遇空指针错误求助
解决Go/Echo+PostgreSQL REST API空指针panic问题
你遇到的runtime error: invalid memory address or nil pointer dereference panic,核心原因是**db变量未初始化,处于nil状态**,调用db.Exec时触发了空指针解引用。
问题分析
在recipe.go的CreateRecipe函数中,直接使用了db.Exec,但你的代码里没有任何初始化PostgreSQL数据库连接的逻辑——db变量只是被引用,却没有被赋值为有效的数据库连接实例,导致调用方法时panic。
解决方案
1. 初始化数据库连接
在程序启动阶段(比如Start函数中)添加PostgreSQL连接初始化逻辑,确保db变量被赋予有效连接。首先需要导入必要的包:database/sql和PostgreSQL驱动github.com/lib/pq。
修改后的代码示例
- server.go:添加数据库连接初始化
import ( "database/sql" "net/http" "your-models-path" // 替换为你的models模块路径 "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" _ "github.com/lib/pq" // 导入pq驱动,无需直接调用 ) var db *sql.DB // 全局db变量,确保recipe.go能访问到 func Start() { // 初始化PostgreSQL连接 var err error // 替换为你的实际数据库连接参数 connStr := "user=your_user password=your_pass dbname=your_db host=localhost port=5432 sslmode=disable" db, err = sql.Open("postgres", connStr) if err != nil { panic(err) } // 验证连接是否有效 if err = db.Ping(); err != nil { panic(err) } // 初始化Echo框架 e := echo.New() e.Use(middleware.CORS()) e.GET("/api/recipes", Home) e.POST("/api/recipes", PostRecipe) e.Logger.Fatal(e.Start(":4000")) }
- recipe.go:确保引用全局的
db变量
import ( "your-models-path" // 替换为你的models模块路径 ) // 这里的db是全局已初始化的数据库连接实例 func CreateRecipe(recipe *models.Recipe) error { query := `INSERT INTO recipes(title, ingredients, description) VALUES($1, $2, $3);` _, err := db.Exec(query, recipe.Title, recipe.Ingredients, recipe.Description) if err != nil { return err } return nil }
2. 可选:依赖注入(更优雅的解耦方式)
如果不想用全局变量,可以将db实例传递给CreateRecipe函数,避免全局变量耦合:
修改recipe.go:
import ( "database/sql" "your-models-path" ) func CreateRecipe(db *sql.DB, recipe *models.Recipe) error { query := `INSERT INTO recipes(title, ingredients, description) VALUES($1, $2, $3);` _, err := db.Exec(query, recipe.Title, recipe.Ingredients, recipe.Description) if err != nil { return err } return nil }
修改router.go的PostRecipe函数:
func PostRecipe(c echo.Context) error { recipe := new(models.Recipe) if err := c.Bind(recipe); err != nil { return err } // 传入已初始化的db实例 err := models.CreateRecipe(db, recipe) if err != nil { return err } return c.JSON(http.StatusCreated, recipe) }
额外检查点
- 确认PostgreSQL服务正在运行,连接字符串里的用户名、密码、数据库名等信息正确。
- 确保
recipes表已在数据库中创建,字段名与SQL语句中的一致。
内容的提问来源于stack exchange,提问作者vfreis09
相关产品推荐
相关产品推荐

