postgresql - 如何使用 Gorm(go struct)将 Postman(json 类型)中的值插入 Postgres
问题描述
我正在尝试编写一些专注于员工管理的简单 CRUD,但在这一点上我有点困惑,所以我应该如何使用 struct 属性json:...
以及gorm:
为新数据库表声明特定数据类型和约束以及发送的特定值来自 Postman 的 json 格式。你在使用 Go-Gorm 吗?
//db file
package tiposDocumentos
import (
"bitbucket.org/username/repositoryname/db"
"bitbucket.org/username/repositoryname/models"
)
// Inserta un nuevo tipo de documento en la base de datos.
func InsertTipoDocumento(tp models.TiposDocumentos) (bool, error) {
db.PsqlDb.AutoMigrate(&tp)
if db.PsqlDb.NewRecord(tp) {
err := db.PsqlDb.Create(&tp)
if err != nil {
return false, nil
}
} else {
return false, errors.New("clave primaria se encuentra en uso")
}
return true, nil
}
package models
type TiposDocumentos struct {
TdoCodigo string `json:"tdo_codigo" gorm:"column:tdo_codigo;type:varchar(3);PRIMARY_KEY;AUTO_INCREMENT:false"`
TdoDescripcion string `json:"tdo_descripcion" gorm:"column:tdo_descripcion;type:varchar(50)"`
TdoCodigoAfip string `json:"tdo_codigo_afip" gorm:"column:tdo_codigo_afip;type:varchar(10)"`
}
package routers
import (
"bitbucket.org/username/repositoryname/db/tiposDocumentos"
"bitbucket.org/username/repositoryname/models"
"encoding/json"
"fmt"
"net/http"
)
var (
tp models.TiposDocumentos
)
// Valida registro recibido y lo inserta en la base de datos.
func PostTiposDocuemntos(w http.ResponseWriter, r *http.Request) {
err := json.NewDecoder(r.Body).Decode(&tp)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
estado, err := tiposDocumentos.InsertTipoDocumento(tp)
if estado == false {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusCreated)
}
至此,Postman 发出请求后,程序成功创建表及其规格,检索代码 201,但该记录未插入表中。 从 pgAdmin4 查看
谢谢☻</p>
在数据库中成功插入新记录后出错:
2020/07/13 12:43:28 http: panic serving 127.0.0.1:64546: runtime error: invalid memory address or nil pointer dereference
goroutine 36 [running]:
net/http.(*conn).serve.func1(0xc000230d20)
C:/Go/src/net/http/server.go:1772 +0x140
panic(0x8085e0, 0xbb5e20)
C:/Go/src/runtime/panic.go:975 +0x3f1
bitbucket.org/emanuelvald/gestion_personal/routers.PostTiposDocuemntos(0x912c20, 0xc00005e000, 0xc000058200)
C:/Projects/Go/src/bitbucket.org/emanuelvald/gestion_personal/routers/tiposDocumentos.go:44 +0x151
net/http.HandlerFunc.ServeHTTP(0x893498, 0x912c20, 0xc00005e000, 0xc000058200)
C:/Go/src/net/http/server.go:2012 +0x4b
github.com/gorilla/mux.(*Router).ServeHTTP(0xc00022a0c0, 0x912c20, 0xc00005e000, 0xc000058000)
C:/Projects/Go/src/github.com/gorilla/mux/mux.go:210 +0xe9
net/http.serverHandler.ServeHTTP(0xc000270000, 0x912c20, 0xc00005e000, 0xc000058000)
C:/Go/src/net/http/server.go:2807 +0xaa
net/http.(*conn).serve(0xc000230d20, 0x9137a0, 0xc000038080)
C:/Go/src/net/http/server.go:1895 +0x873
created by net/http.(*Server).Serve
C:/Go/src/net/http/server.go:2933 +0x363
解决方案
考虑一下当 err 不是 nil 时会发生什么:
if err != nil {
return false, nil
}
然后你这样做:
estado, err := tiposDocumentos.InsertTipoDocumento(tp)
if estado == false {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
所以,estado
是假的,然后你尝试访问err.Error()
,但是err
是nil
,所以你得到一个
invalid memory address or nil pointer dereference
您可能只需要这样做:
if err != nil {
return false, err
}
然后做:
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
推荐阅读
- c# - 在 Unity C# 中访问值的问题
- react-native - React-Native webview - 未处理的承诺:IOS中的空白
- javascript - 首次访问 Javascript 后 30 天
- javascript - Firebase 身份验证并在 MySQL 中存储用户
- node.js - 如何在 Firebase 云功能中使用 github 机密
- c# - c#自动化停止进程
- jquery - 响应式设计初学者的 CSS 基础
- javascript - 类型错误:oldMember.roles.every 不是函数
- java - Spring核心具有多个上下文的同一类
- typescript - 根据另一个字符串属性的值解析一个属性的动态类型