dppcyt6157 2019-08-27 06:56
浏览 420
已采纳

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

  • 写回答

1条回答 默认 最新

  • doujiao1538 2019-08-27 07:29
    关注

    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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料