如何使用 sqlx 扫描嵌套结构?

kuz*_*zua 6 postgresql go sqlx

假设我有两个模型,

    type Customer struct {
       Id      int     `json:"id" db:"id"`
       Name    string  `json:"name" db:"name"`
       Address Address `json:"adress"`
    }
    
    type Address struct {
       Street string `json:"street" db:"street"`
       City   string `json:"city" db:"city"`
    }

    // ...

    customer := models.Customer{}
    err := db.Get(&customer , `select * from users where id=$1 and name=$2`, id, name)
Run Code Online (Sandbox Code Playgroud)

但此扫描会引发错误:missing destination name street in *models.Customer

难道我做错了什么?正如你所看到的,我已经更新了该值对应的数据库。我仔细检查了一下,所以区分大小写应该不是问题。或者使用https://github.com/jmoiron/sqlx是不可能的吗?

我可以在文档中看到它,但仍然不知道如何解决它。 http://jmoiron.github.io/sqlx/#advancedScanning

users表声明为:

    CREATE TABLE `users` (
      `id` varchar(256) NOT NULL,
      `name` varchar(150) NOT NULL,
      `street` varchar(150) NOT NULL,
      `city` varchar(150) NOT NULL,
    )
Run Code Online (Sandbox Code Playgroud)

bla*_*een 9

您发布的链接为您提供了有关如何执行此操作的提示:

StructScan 看似复杂。它支持嵌入式结构,并使用 Go 用于嵌入式属性和方法访问的相同优先级规则分配给字段。

因此,鉴于您的数据库架构,您可以简单地嵌入AddressCustomer

type Customer struct {
   Id     int    `json:"id" db:"id"`
   Name   string `json:"name" db:"name"`
   Address
}
Run Code Online (Sandbox Code Playgroud)

在您的原始代码中,是一个具有自己的Address标签的字段这是不正确的,顺便说一句,您的架构根本没有列。(看来您从代码片段中编辑了它)dbaddress

通过将结构嵌入到其中CustomerAddress包括标签的字段将被提升到Customer并且sqlx能够从查询结果中填充它们。

警告:嵌入字段还会展平任何 JSON 编组的输出。它将变成:

type Customer struct {
   Id     int    `json:"id" db:"id"`
   Name   string `json:"name" db:"name"`
   Address
}
Run Code Online (Sandbox Code Playgroud)

如果您想根据原始结构标签将streetcity放入 JSON对象中,最简单的方法可能是将 DB 结构重新映射到您的原始类型。address

您还可以将查询结果扫描到 a 中map[string]interface{},但是您必须小心Postgres 数据类型在 Go 中的表示方式