【问题标题】:How to scan a QueryRow into a struct with pgx如何使用 pgx 将 QueryRow 扫描到结构中
【发布时间】:2020-08-25 12:38:22
【问题描述】:

我们正在使用一个包含很多字段的用户结构,如下所示:

type user struct {
    ID       int    `json:"id,omitempty"`
    UUID     string `json:"uuid,omitempty"`
    Role     int    `json:"role,omitempty"`
    Name     string `json:"name,omitempty"`
    Surname  string `json:"surname,omitempty"`
    Phone    string `json:"phone,omitempty"`
    Email    string `json:"email,omitempty"`
    Street   string `json:"street,omitempty"`
    City     string `json:"city,omitempty"`
    Password string `json:"password,omitempty"`
}

还有一个通过电子邮件获取用户的功能:

func getUserByEmail(email string) (u user, err error) {
    row := db.Psql.QueryRow(
        context.Background(),
        "SELECT * FROM users WHERE email=$1",
        email)
    err = row.Scan(&u.ID, &u.UUID, &u.Role, &u.Name, &u.Surname, &u.Phone, &u.Email, &u.Street, &u.City, &u.Password)
    if err != nil {
        log.Fatal(err)
    }
    return
}

有没有办法直接扫描到一个结构而不是它的所有属性?理想情况下:

row.Scan(&u)

【问题讨论】:

    标签: go struct psql pgx


    【解决方案1】:

    还有另一个库scany。 它适用于pgx 本机接口和database/sql

    package main
    
    import (
        "context"
    
        "github.com/jackc/pgx/v4/pgxpool"
    
        "github.com/georgysavva/scany/pgxscan"
    )
    
    type User struct {
        ID    string
        Name  string
        Email string
        Age   int
    }
    
    func main() {
        ctx := context.Background()
        db, _ := pgxpool.Connect(ctx, "example-connection-url")
    
        var users []*User
        pgxscan.Select(ctx, db, &users, `SELECT id, name, email, age FROM users`)
        // users variable now contains data from all rows.
    }
    

    它经过了很好的测试和记录,并且比 sqlx 的概念少得多。

    免责声明,我是这个库的作者。

    【讨论】:

      【解决方案2】:

      不是普通的database/sql,而是有一个名为sqlx 的扩展库,它建立在database/sql 之上,并添加了一些有用的扩展,例如将行解组到结构(包括嵌套)、切片和数组中:

      type Place struct {
          Country       string
          City          sql.NullString
          TelephoneCode int `db:"telcode"`
      }
      
      rows, err := db.Queryx("SELECT * FROM place")
      for rows.Next() {
          var p Place
          err = rows.StructScan(&p)
      }
      

      查看documentation 并查找StructScan

      【讨论】:

        【解决方案3】:

        目前,pgx 库中不支持直接扫描到结构。最好使用像 go-pg 这样的 ORM,它为您提供了许多数据库查询和扫描功能。

        【讨论】:

        • 没有人应该拉入整个 ORM 进行结构扫描
        • @user4893106 我建议使用 ORM 而不是工具包(pgx 是工具包而不是 ORM),因为 OP 想要的功能是类似 ORM 的功能。我并不是说两者都使用,例如添加 go-pg 仅用于扫描。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-05
        • 1970-01-01
        相关资源
        最近更新 更多