golang null.String解码无法正常工作

Trying to fix this problem i'm having with my api im building.

db:

DROP TABLE IF EXISTS contacts CASCADE;
CREATE TABLE IF NOT EXISTS contacts (
        uuid UUID UNIQUE PRIMARY KEY,
        first_name varchar(150),
);



DROP TABLE IF EXISTS workorders CASCADE;
CREATE TABLE IF NOT EXISTS workorders (
        uuid UUID UNIQUE PRIMARY KEY,
        work_date timestamp WITH time zone,
        requested_by UUID REFERENCES contacts (uuid) ON UPDATE CASCADE ON DELETE CASCADE,

);

struct:

https://gopkg.in/guregu/null.v3

type WorkorderNew struct {
    UUID               string      `json:"uuid"`
    WorkDate           null.Time   `json:"work_date"`
    RequestedBy        null.String `json:"requested_by"`
}

api code:

workorder := &models.WorkorderNew{}
if err := json.NewDecoder(r.Body).Decode(workorder); err != nil {
    log.Println("decoding fail", err)
}
// fmt.Println(NewUUID())
u2, err := uuid.NewV4()
if err != nil {
    log.Fatalf("failed to generate UUID: %v", err)
}

q := `
            INSERT
            INTO workorders
                (uuid,
                work_date,
                requested_by
                )
            VALUES
                ($1,$2,$3)
            RETURNING uuid;`

statement, err := global.DB.Prepare(q)
global.CheckDbErr(err)

fmt.Println("requested by", workorder.RequestedBy)

lastInsertID := ""
err = statement.QueryRow(
    u2,
    workorder.WorkDate,
    workorder.RequestedBy,
).Scan(&lastInsertID)
global.CheckDbErr(err)

json.NewEncoder(w).Encode(lastInsertID)

When I send an API request with null as the value it works as expected but when i try to send a "" as the value for the null.String or the null.Time it fails

works:

{  
   "work_date":"2016-12-16T19:00:00Z",
   "requested_by":null
}

not working:

{  
   "work_date":"2016-12-16T19:00:00Z",
   "requested_by":""
}

Basically when i call the QueryRow and save to database the workorder.RequestedBy value should be a null and not the "" value im getting thanks

sql
dongwen1909
dongwen1909 然后不要使用null.String,而是实现您自己的自定义类型。由于在json中,空字符串“”与null不同,因此null.String的行为是正确的。因此,如果您的要求与null.String支持的要求不同,那么请不要使用它。
大约一年之前 回复
duanchi4184
duanchi4184 我期望当我执行queryrow时,它将RequestedBy保存为数据库中的null而不是将其另存为“”(这在我的模式中失败)
大约一年之前 回复
dongyao1895
dongyao1895 “失败”或“不起作用”是什么意思?您遇到错误了吗?如果是这样,请在您的问题中包括该错误。您得到的结果与预期的有所不同吗?如果是这样,请在问题中包括预期和实际结果。
大约一年之前 回复

1个回答



如果要将空字符串视为null,则至少有两个选择。</ p>

” 扩展“ null.String </ code>:</ p>

  type MyNullString struct {
null.String
}

func(ns * MyNullString)UnmarshalJSON( 数据[] byte)错误{
,如果string(data)==“”{
ns.Valid = false
返回nil
}
ns.String.UnmarshalJSON(data)
}
</ code> </ pre>

或在查询中使用 NULLIF </ code>:</ p>

  INSERT INTO workorders(
uuid

,工作日期
,request_by
)值(
$ 1
,$ 2
,NULLIF($ 3,'')

返回uuid
</ code> </ pre>


更新</ strong>:</ p>

要扩展 null.Time </ code>,您必须了解该类型 null.Time.Time </ code> < / a>是 struct </ em>。 内置的 len </ code> 函数可用于切片,数组,指向 数组,地图,频道和字符串。 不是结构。 因此,在这种情况下,您可以通过将 data </ code>参数(它是一个字节切片)转换为字符串并将其与包含</ em>一个空字符串的字符串进行比较,例如 </ p>

  type MyNullTime struct {
null.Time
}

func(ns * MyNullTime)UnmarshalJSON(data [] byte )错误{
如果string(data)==“”{
ns.Valid = false
返回nil
}
返回ns.Time.UnmarshalJSON(data)
}
</ code > </ pre>
</ div>

展开原文

原文

If you want to treat empty strings as nulls you have at least two options.

"Extend" null.String:

type MyNullString struct {
    null.String
}

func (ns *MyNullString) UnmarshalJSON(data []byte) error {
    if string(data) == `""` {
        ns.Valid = false
        return nil
    }
    ns.String.UnmarshalJSON(data)
}

Or use NULLIF in the query:

INSERT INTO workorders (
    uuid
    , work_date
    , requested_by
) VALUES (
    $1
    , $2
    , NULLIF($3, '')
)
RETURNING uuid

Update:

To extend the null.Time you have to understand that the type of null.Time.Time is a struct. The builtin len function works on slices, arrays, pointers to arrays, maps, channels, and strings. Not structs. So in this case you can check the data argument, which is a byte slice, by converting it to a string and comparing it to a string that contains an empty string, i.e. it has two double quotes and nothing else.

type MyNullTime struct {
    null.Time
}

func (ns *MyNullTime) UnmarshalJSON(data []byte) error {
    if string(data) == `""` {
        ns.Valid = false
        return nil
    }
    return ns.Time.UnmarshalJSON(data)
}

dongzhuo1958
dongzhuo1958 就像魅力一样工作,再次感谢您的帮助。。。。。。。。。。。。。。。。。。。。。。。。。。。
大约一年之前 回复
douzhanjia0773
douzhanjia0773 我已经为答案添加了一个更新,请尝试一下,让我知道它是否可行,因为我没有测试过它或其他任何东西。
大约一年之前 回复
douzi6992
douzi6992 谢谢您的第一个解决方案是完美的。 我试图为null.time实现它,但是我对此也有些迷惑,您能否告诉我如何做到这一点呢? func(ns * MyNullTime)UnmarshalJSON(data [] byte)错误{如果err:= ns.Time.UnmarshalJSON(data); err!= nil {return err} ns.Valid = len(ns.Time.Time)> 0 //如果为空,则设置为有效= false return nil}
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐