Postgresql 插入数据库时,如何忽略嵌入式结构字段?
我有2个数据库表; A有3列,它们是X、Y、Z B有两列,它们是X,W 我的围棋结构是这样的Postgresql 插入数据库时,如何忽略嵌入式结构字段?,postgresql,go,go-gorm,Postgresql,Go,Go Gorm,我有2个数据库表; A有3列,它们是X、Y、Z B有两列,它们是X,W 我的围棋结构是这样的 type Base struct { X int Y int } type A struct { Base Z int } type B struct { Base W int } a := A{Base: Base{X: 1, Y:2}, Z: 3} b := B{Base: Base{X: 1}, W: 4} 我像这样初始化我的
type Base struct {
X int
Y int
}
type A struct {
Base
Z int
}
type B struct {
Base
W int
}
a := A{Base: Base{X: 1, Y:2}, Z: 3}
b := B{Base: Base{X: 1}, W: 4}
我像这样初始化我的结构
type Base struct {
X int
Y int
}
type A struct {
Base
Z int
}
type B struct {
Base
W int
}
a := A{Base: Base{X: 1, Y:2}, Z: 3}
b := B{Base: Base{X: 1}, W: 4}
当我想使用gorm.io ORM将这些文件插入数据库时,“a”插入时没有任何问题,但“b”无法插入,因为postgresql会给我一个类似以下的错误
pq: column "y" of relation "B" does not exist
如何在不创建另一个没有“Y”字段的基础模型的情况下将“b”插入数据库?当您将结构分配给另一个结构,并创建结构实例时,所有结构字段都已填充默认数据类型值 例如:
int
默认值为0
这个问题有两个解决方案
Base
struct),只创建A
和B
。像这样:(也许你知道这个解决方案。)struct标记
防止使用gorm
插入type Base struct {
X int
Y int `json:"y,omitempty"`
}
type A struct {
Base
Z int
}
type B struct {
Base
W int
}
我认为您没有正确地声明模型,因为文档“Base”应该在A和B中嵌入标记,然后就可以了。为了您更好地理解我张贴您的代码与修改。请注意,我已经在我的机器上进行了测试,它就像魅力一样 这是模型声明
type Base struct {
X int `json:"x"`
Y int `json:"y"`
}
type A struct {
Base `gorm:"embedded"`
Z int `json:"z"`
}
type B struct {
Base `gorm:"embedded"`
W int `json:"w"`
}
以下是您了解的主要功能
func main() {
fmt.Println("vim-go")
db, err := gorm.Open("postgres", "host=localhost port=5432 user=postgres
dbname=testd password=postgres sslmode=disable")
if err != nil {
log.Panic("error occured", err)
}
db.AutoMigrate(&A{}, &B{})
a := &A{Base: Base{X: 1, Y: 2}, Z: 3}
b := &B{Base: Base{X: 1}, W: 3}
if err := db.Create(a).Error; err != nil {
log.Println(err)
}
if err := db.Create(b).Error; err != nil {
log.Println(err)
}
fmt.Println("everything is ok")
defer db.Close()
}
请务必检查模型声明和标签的文档。
注:Y字段将出现在B表中,但值为零 主程序包
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type SearchResult struct {
OrderNumber string `json:"orderNumber"`
Qunatity interface{} `json:"qty"`
Price string `json:"price"`
OrderType interface{} `json:"type"`
ItemQty string `json:"itemQty"`
}
type Or []SearchResult
func fieldSet(fields ...string) map[string]bool {
set := make(map[string]bool, len(fields))
for _, s := range fields {
set[s] = true
}
return set
}
func (s *SearchResult) SelectFields(fields ...string) map[string]interface{} {
fs := fieldSet(fields...)
rt, rv := reflect.TypeOf(*s), reflect.ValueOf(*s)
out := make(map[string]interface{}, rt.NumField())
for i := 0; i < rt.NumField(); i++ {
field := rt.Field(i)
jsonKey := field.Tag.Get("json")
if fs[jsonKey] {
out[jsonKey] = rv.Field(i).Interface()
}
}
return out
}
func main() {
result := &SearchResult{
Date: "to be honest you should probably use a time.Time field here,
just sayin",
Industry: "rocketships",
IdCity: "interface{} is kinda inspecific, but this is the idcity field",
City: "New York Fuckin' City",
}
b, err := json.MarshalIndent(result.SelectFields("orderNumber", "qty"), "", " ")
if err != nil {
panic(err.Error())
}
var or Or
fmt.Print(string(b))
or=append(or,*result)
or=append(or,*result)
for i := 0; i < len(or); i++ {
c, err := json.MarshalIndent(or[i].SelectFields("idCity", "city", "company"),
"", " ")
if err != nil {
panic(err.Error())
}
fmt.Print(string(c))
}
}
进口(
“编码/json”
“fmt”
“反映”
)
类型SearchResult结构{
OrderNumber字符串`json:“OrderNumber”`
质量接口{}`json:“数量”`
价格字符串`json:“价格”`
OrderType接口{}`json:“类型”`
ItemQty字符串`json:“ItemQty”`
}
键入或[]搜索结果
func字段集(字段…字符串)映射[字符串]布尔{
设置:=make(映射[字符串]布尔,len(字段))
对于uz,s:=范围字段{
设置[s]=true
}
返回集
}
func(s*SearchResult)SelectFields(fields…string)映射[string]接口{}{
fs:=字段集(字段…)
rt,rv:=reflect.TypeOf(*s),reflect.ValueOf(*s)
out:=make(映射[string]接口{},rt.NumField())
对于i:=0;i
一种方法是使用结构中的空字段,另一种方法是遍历结构字段,这很昂贵。
如果性能对您来说无关紧要,那么您可以参考上面的代码片段。谢谢您的回复,但这并不能解决我的问题。在这个问题中,我想演示一个小示例,但在我的项目中,我有更多的结构嵌入了Base struct。因此,您的第一个解决方案并没有按照我想要的方式解决问题(但是这个解决方案比创建另一个没有“Y”的基本结构要好)。对于你的第二个解决方案,我以前试过这个,但没有成功。@Omerfk我想另一个解决方案是使用map[string]接口{}。然后为其创建动态查询。