使用GORM操作MariaDB时Create方法失效,报SQL语法错误
问题解决:GORM调用Create方法时MariaDB SQL语法错误
问题原因
- 重复ID字段冲突:你的
Todo结构体同时嵌入了gorm.Model(已内置ID字段)和自定义的ID int,导致GORM生成SQL时重复输出id字段,干扰了主键生成逻辑。 - 数据库类型识别错误:GORM生成了PostgreSQL专属的
RETURNING语句,但MariaDB不支持该语法,说明GORM未正确识别数据库类型(可能误用驱动或DSN配置错误)。
解决步骤
1. 修复Todo结构体,移除重复ID字段
gorm.Model已经包含ID(默认类型uint),无需重复定义。修改后的结构体:
type Todo struct { gorm.Model Title string `json:"title"` Done int `json:"done"` Body string `json:"body"` }
若需要ID为int类型,可覆盖内置字段而非新增:
type Todo struct { gorm.Model ID int `gorm:"primaryKey" json:"id"` // 覆盖内置uint类型的ID Title string `json:"title"` Done int `json:"done"` Body string `json:"body"` }
2. 确保使用正确的MariaDB驱动与DSN配置
连接MariaDB必须使用MySQL驱动(github.com/go-sql-driver/mysql),正确的DSN格式如下:
import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { dsn := "用户名:密码@tcp(127.0.0.1:3306)/数据库名?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) // 错误检查逻辑... }
注意:
- 禁止使用PostgreSQL驱动
parseTime=True是必填参数,用于GORM处理时间类型
3. 添加错误检查(推荐)
在Create调用处增加错误捕获,便于快速排查问题:
if err := db.Create(&newTodo).Error; err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": err.Error(), }) }
修改后的完整路由示例
app.Post("/api/todos", func(c *fiber.Ctx) error { todo := &Todo{} if err := c.BodyParser(todo); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": err.Error(), }) } newTodo := &Todo{ Title: todo.Title, Body: todo.Body, Done: 0, } if err := db.Create(&newTodo).Error; err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": err.Error(), }) } var todos []Todo db.Find(&todos) return c.JSON(todos) })
完成以上修改后,GORM将生成符合MariaDB语法的SQL(不再包含RETURNING语句),Create方法即可正常工作。
内容的提问来源于stack exchange,提问作者mikoo
相关产品推荐
相关产品推荐

