use*_*072 6 arrays enums go pgx sqlc
我正在使用sqlc
and pgx/v5
,并且对于用户定义的枚举类型的 postgres 数组出现以下错误:
Error: can't scan into dest[1]: cannot scan unknown type (OID 16385) in text format into *pgtype.Array[my-app/sqlc.Option]
架构和查询:
CREATE TYPE option AS ENUM (
'OPT_1',
'OPT_2',
'OPT_3'
);
CREATE TABLE IF NOT EXISTS blah (
id BIGINT PRIMARY KEY,
options option[] NOT NULL DEFAULT '{OPT_1}'
);
-- name: CreateBlah :one
INSERT INTO blah (
id
) VALUES (
$1
)
RETURNING *;
Run Code Online (Sandbox Code Playgroud)
sqlc
似乎正确生成了类型:
CREATE TYPE option AS ENUM (
'OPT_1',
'OPT_2',
'OPT_3'
);
CREATE TABLE IF NOT EXISTS blah (
id BIGINT PRIMARY KEY,
options option[] NOT NULL DEFAULT '{OPT_1}'
);
-- name: CreateBlah :one
INSERT INTO blah (
id
) VALUES (
$1
)
RETURNING *;
Run Code Online (Sandbox Code Playgroud)
我可以通过定义自己的类型并实现接口,scanner
然后在配置中指定覆盖来解决这个问题sqlc
:
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.16.0
package sqlc
import (
"database/sql/driver"
"fmt"
"github.com/jackc/pgx/v5/pgtype"
)
type Option string
const (
OptionOPT1 Option = "OPT_1"
OptionOPT2 Option = "OPT_2"
OptionOPT3 Option = "OPT_3"
)
func (e *Option) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = Option(s)
case string:
*e = Option(s)
default:
return fmt.Errorf("unsupported scan type for Option: %T", src)
}
return nil
}
type NullOption struct {
Option Option
Valid bool // Valid is true if Option is not NULL
}
// Scan implements the Scanner interface.
func (ns *NullOption) Scan(value interface{}) error {
if value == nil {
ns.Option, ns.Valid = "", false
return nil
}
ns.Valid = true
return ns.Option.Scan(value)
}
// Value implements the driver Valuer interface.
func (ns NullOption) Value() (driver.Value, error) {
if !ns.Valid {
return nil, nil
}
return string(ns.Option), nil
}
func (e Option) Valid() bool {
switch e {
case OptionOPT1,
OptionOPT2,
OptionOPT3:
return true
}
return false
}
type Blah struct {
ID int64
Options pgtype.Array[Option]
}
Run Code Online (Sandbox Code Playgroud)
// sqlc.yaml
...
overrides:
- column: "blah.options"
go_type: "myapp/pgx/types.Options" // <-- cannot be "sqlc.Options"
Run Code Online (Sandbox Code Playgroud)
但底层类型必须是pgtype.Array[string]
,但不能是pgtype.Array[Option]
,因为:
sqlc
无法覆盖与生成代码相同的包中的类型sqlc
生成的类型,因为它会导致导入周期(pkg importing和 pkg importing )Option
Options
types
sqlc.Option
sqlc
types.Options
Option
这意味着我失去了类型安全性以及sqlc
.
从这个pgx/v5
github 问题来看,我认为我需要使用该pgx/v5
SQLScanner
类型并调用它的RegisterDefaultPgType
方法,但是,我不确定这是否准确,或者如何实际做到这一点。
pgx
在不失去类型安全性的情况下识别用户定义的枚举类型的 postgres 数组的正确方法是什么?
在 pgx 上注册类型对我有用
dataTypeNames := []string{
"my_custom_type_name",
// I think this one prefixed with "_" is used for arrays
"_my_custom_type_name",
}
conn := // get *pgx.Conn
for _, typeName := range dataTypeNames {
dataType, _ := conn.LoadType(ctx, typeName)
conn.TypeMap().RegisterType(dataType)
}
Run Code Online (Sandbox Code Playgroud)
有了这样的东西,你就可以做到这一点,而无需手动定义自定义类型。
归档时间: |
|
查看次数: |
1333 次 |
最近记录: |