You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gorm中Model(&Usertable).Create(data)如何传入正确表名?

问题描述

尝试向GORM定义的表中插入数据时出现表名空的错误,以下是相关信息:

包结构

gorm
|- server
   |- insertRow.go
|- pkg
   |- models
      |- mytable.go
   |- database
      | - connectdb.go

mytable.go 代码

package models

type Usertable struct {
    Firstname    string `gorm:"column:firstname"`
    Lastname  string `gorm:"column:lastname"`
}

func (fmap *Usertable) TableName() string { return "usertable" }

insertRow.go 初始代码

package main
import (
        "fmt"
       "gorm/pkg/models"
        "gorm/pkg/database"
)

func  main() {
  params := map[string]interface{} {
        "Firstname" : "MyFirstName",
        "Lastname" : "LastName" ,
 }
        db, _ := database.NewStorage("postgres", "testdb")

        var user models.Usertable

        err := db.DB.Debug().Model(&user).Create(params)
        if err != nil {
                fmt.Println("Error :=", err)
        } else {
                fmt.Println("Success")
        }

}

数据库表定义

testdb=# \d+ usertable
                                 Table "public.usertable"
  Column   | Type | Collation | Nullable | Default | Storage  | Stats target | Description
-----------+------+-----------+----------+---------+----------+--------------+-------------
 firstname | text |           |          |         | extended |              |
 lastname  | text |           |          |         | extended |              |

执行错误信息

(/root/gorm/cloudOps/server/testDB/insertRow.go:17)
[2023-09-23 23:51:26]  pq: zero-length delimited identifier at or near """"

(/root/gorm/cloudOps/server/testDB/insertRow.go:17)
[2023-09-23 23:51:26]  [0.45ms]  **INSERT INTO "" DEFAULT VALUES RETURNING "".***
[0 rows affected or returned ]
Error := &{{{0 0} 0 0 {{} 0} {{} 0}} map[Firstname:MyFirstName Lastname:LastName] pq: zero-length delimited identifier at or near """" 0 0xc0000a4b60 false 2 {0xc0001a3d60} 0xc0001e8420 {{0 0} {[] {} 0xc00021cc20} map[] 0} 0xc0000a4c30 <nil> 0xc0000a2c78 false <nil>}

可见生成的INSERT语句中表名为空,尝试了以下写法但结果相同:

package main
import (
    "fmt"
//       "gorm/pkg/models"
    "gorm/pkg/database"
    "gorm.io/gorm"
)

type Usertable struct {
    gorm.Model
    Firstname    string `gorm:"column:firstname"`
    Lastname  string `gorm:"column:lastname"`
}

func  main() {
  params := map[string]interface{} {
    "Firstname" : "MyFirstName",
    "Lastname" : "LastName" ,
 }
    db, _ := database.NewStorage("postgres", "testdb")


    err := db.DB.Debug().Model(&Usertable{}).Create(params)
    if err != nil {
        fmt.Println("Error :=", err)
    } else {
        fmt.Println("Success")
    }

}

请问插入命令存在什么问题?如何向Create调用传递正确的表名?


解决方案

问题核心:用map作为Create参数时,GORM无法通过Model指定的结构体获取表名。因为Create(map)的写法会让GORM忽略Model里的表元信息,转而尝试从映射中推断,但映射没有表名相关数据,最终生成空表名的SQL。

两种解决办法:

方法1:用结构体实例替代map作为Create参数

直接构造Usertable结构体实例,GORM会自动识别表名(包括TableName()方法定义的名称):

func main() {
    db, err := database.NewStorage("postgres", "testdb")
    if err != nil {
        fmt.Println("数据库连接失败:", err)
        return
    }

    user := models.Usertable{
        Firstname: "MyFirstName",
        Lastname:  "LastName",
    }

    err = db.DB.Debug().Create(&user).Error
    if err != nil {
        fmt.Println("插入错误:", err)
    } else {
        fmt.Println("插入成功")
    }
}

方法2:必须用map时,显式指定表名

使用Table()方法直接指定表名,替代Model()的作用:

func main() {
    params := map[string]interface{}{
        "Firstname": "MyFirstName",
        "Lastname":  "LastName",
    }

    db, err := database.NewStorage("postgres", "testdb")
    if err != nil {
        fmt.Println("数据库连接失败:", err)
        return
    }

    // 直接用Table指定表名
    err = db.DB.Debug().Table("usertable").Create(params).Error
    if err != nil {
        fmt.Println("插入错误:", err)
    } else {
        fmt.Println("插入成功")
    }
}

额外注意事项

  1. 不要忽略database.NewStorage的错误返回,必须检查连接是否成功,避免基于无效DB实例执行操作。
  2. 第一种方法更贴合GORM设计范式,能利用结构体的标签验证、自动字段映射等特性,优先推荐使用。

内容的提问来源于stack exchange,提问作者Ravindra Rao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:37:46