【问题标题】:map an interface inside struct filed into a postgres db column datatype将 struct 字段内的接口映射到 postgres db 列数据类型
【发布时间】:2021-11-25 16:45:24
【问题描述】:

我有一个结构,其中一个字段类型是 interface ,我如何将接口映射到 db 字段(应该是列类型)以便我可以检索它?在下面的代码中,我想知道如何在数据库中映射任务字段,以便我可以在数据库中存储“a”和“b”。如果它不是一个接口,我可以用底层 struct 映射。我在使用 postgres 包中没有任何限制

package main

import (
    "fmt"
)

type Sai struct {
    Name string. // can map this in db as string
    Task Test.  // how should i map this
}
type Test interface {
    Print()
}
type dummyStruct1 struct {
    Name StringStruct
}

type StringStruct struct {
    Name string
}
type dummyStruct2 struct {
    Name StringStruct
}

func main() {
    fmt.Println("Hello, playground")

    s1 := dummyStruct1{Name: StringStruct{"jon"}}
    s2 := dummyStruct1{Name: StringStruct{"smith"}}

    a := Sai{Name: "task1", Task: s1.Hello()}
    b := Sai{Name: "task1", Task: s2.Hello()}
    a.Task.Print()
    b.Task.Print()

}
func (s StringStruct) Print() {
    fmt.Println(s.Name)
}
func (d dummyStruct1) Hello() StringStruct {
    return d.Name
}
func (d dummyStruct2) Hello() StringStruct {
    return d.Name
}

【问题讨论】:

  • 目标列的类型是什么?
  • 这就是我正在寻找的答案
  • 要存储在数据库中的列类型是什么,底层值是接口,如果我必须重构问题,请告诉我,重构问题的建议也是开放的 :)
  • 您需要选择一种可用于表示实现Test 接口类型的每个 类型的类型。使用 PostgreSQL,您可以使用 jsonbtextbytea 等。但困难的部分是实现从 Go 类型到 Pg 类型的转换并返回。该实现将取决于潜在的 Go 类型以及您决定的 Pg 列类型是什么。
  • 你能给我看一个 postgres 模式的例子吗?只为以上

标签: postgresql go


【解决方案1】:

如果你是实现接口Test的具体类型的人:

如果你可以修改Test 本身的话:

import (
  "database/sql"
  "database/sql/driver"
)
// other stuff
type Test interface{
  sql.Scanner
  driver.Valuer
  Print()
}

否则创建一个新类型TestDB

import (
  "database/sql"
  "database/sql/driver"
)
// other stuff
type TestDB interface{
  sql.Scanner
  driver.Valuer
  Test
}

现在无论您创建哪种新类型都必须实现sql.Scannerdriver.Valuer 接口。 lib/pq 在将值写入数据库或从数据库扫描数据时会在内部自动使用它们。

举个例子

// Assuming Test can implement Valuer and Scanner interfaces
package main

import (
    "fmt"
    "database/sql"
    "database/sql/driver"
)

type Sai struct {
    Name string // can map this in db as string
    Task Test  // how should i map this
}
type Test interface {
    sql.Scanner
    driver.Valuer
    Print()
}

type StringStruct struct {
    Name string
}

func main() {
    ...
}

func (s StringStruct) Print() {
    fmt.Println(s.Name)
}

func (s StringStruct) Value() (driver.Value, error) {
    return s.Name
}

func (s *StringStruct) Scan(src interface{}) error {
    v, ok := src.(string)
    if !ok {
        return fmt.Errorf("not a string")
    }
    s.Name = v
}

// more code
...
...

现在您可以在 postgres 中存储 StringStruct 类型的任何内容 - 这也是 Test 类型的简单 varchartext。这也不仅限于strings,尽管正如您所知 - 事实上这是我目前从 pq 存储和检索 json 的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 2014-11-02
    • 2016-04-15
    • 2022-12-10
    • 2020-11-29
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    相关资源
    最近更新 更多