Go - 使用 pgtypes 的正确方法

Kar*_*njs 6 go libpq pgx sqlc

我正在开发一个简单的Go服务来连接到数据库以进行基本查询。我用来sqlc生成Go与数据库交互的函数。lib/pq当从现在切换驱动程序时,pgx/v5数据库字段的类型而pgtypes不是Go类型。这是一个例子:

而不是这个:

    type ListAccountsParams struct {
        Owner  string `json:"owner"`
        Limit  int32  `json:"limit"`
        Offset int32  `json:"offset"`
    }
Run Code Online (Sandbox Code Playgroud)

我现在明白了:

    type ListAccountsParams struct {
        Owner  pgtype.Text `json:"owner"`
        Limit  pgtype.Int4 `json:"limit"`
        Offset pgtype.Int4 `json:"offset"`
    }
Run Code Online (Sandbox Code Playgroud)

然而我发现使用的唯一方法pgtypes是这个:

    owner := pgtype.Text{
        String: "Craigs List",
        Valid: true,
    }
Run Code Online (Sandbox Code Playgroud)

而不是仅仅做owner := "Craigs List"。对于数字类型就更矫枉过正了,我找到的所有实现都是这样的:

    pgtype.Numeric{
    Int: big.NewInt(-543), 
    Exp: 3, 
    Status: pgtype.Present
    }
Run Code Online (Sandbox Code Playgroud)

使用sqlc配置文件,我可以覆盖这些类型以支持标准类型,但对我来说必须覆盖 postgres类型等等Go是没有意义的......textstring

在我看来,这不是使用这些类型的最佳方式,这对我来说是违反直觉的。所以我的问题是,我做得对吗?有不同的方法吗?最终,有没有一种方法可以配置sqlc为使用Go类型而不是pgtypes同时使用pgx/v5驱动程序?

Fre*_*man 2

您可以编辑sqlc配置文件来为要使用 Go 类型而不是类型的字段指定自定义类型,并通过在文件pgtype中指定所需的 Go 类型来覆盖类型sqlc.yaml

types:
  - name: ListAccountsParams
    fields:
      - name: Owner
        goType: string
      - name: Limit
        goType: int32
      - name: Offset
        goType: int32
Run Code Online (Sandbox Code Playgroud)

请注意,直接使用 Go 类型可能会导致与数据库交互时潜在的类型不匹配或其他问题,而pgtype类型是专门为处理 PostgreSQL 特定的数据类型而设计的,并提供一定程度的类型安全性和兼容性!

更新

根据您的评论,当使用pgx/v5驱动程序时sqlc,生成的代码使用pgtype类型来处理 PostgreSQL 特定的数据类型,这是sqlc使用驱动程序时的默认行为,并且您使用类型(例如和)pgx/v5描述的方式是正确的处理这些类型的方式,例如,在处理类型时,您需要将字段设置为所需的值并将字段设置为。pgtypepgtype.Textpgtype.Int4pgtype.TextStringValidtrue

对于数值类型,该pgtype.Numeric类型需要设置IntExp、 和字段,这是因为该类型将数值表示为任意精度整数 ( )、指数 ( ) 和状态 ( ) 指示该值是否为存在或无效!Statuspgtype.NumericIntExpStatus

  • @KarlsMaranjs我更新了我的答案,不幸的是,没有常用的替代方法来处理这些“pgtype”类型,“pgtype”包提供了必要的类型和方法,以类型安全的方式处理 PostgreSQL 特定的数据类型,如果您发现 `pgtype` 类型的使用很麻烦,一种可能的方法是编写辅助函数或方法来简化创建和使用 `pgtype` 类型的过程,例如,您可以创建一个函数,它采用一个字符串并返回一个“pgtype.Text”类型,其中“Valid”字段设置为“true”! (2认同)