Postgresql 插入数据库时,如何忽略嵌入式结构字段?

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} 我像这样初始化我的

我有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}
当我想使用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]接口{}。然后为其创建动态查询。