使用sqlx进行struct嵌入不会从db返回值

时间:2017-04-21 22:17:14

标签: go sqlx

我有一个结构,其时间字段可能为零:

type Order struct {
    ...
    PickupTime  *time.Time    `json:"-"`
}

我想将其保存到包含sqlx的数据库,因此我认为我需要按照建议here使用pq.NullTime

我没有更新Order对象(我不想将DB代码泄漏到模型层中),而是认为我可以在PgOrder中嵌入Order并更改PickupTime类型:

type PgOrder struct {
    Order
    PickupTime pq.NullTime
}

问题在于,当我只是更新数据库中的Order,然后转身并获取该订单时,返回的PickupTime为空。

// update
func (pg Postgres) UpdateOrderPickupTime(order *Order, pickupTime time.Time) error {
    _, err := pg.Exec(`UPDATE orders SET pickup_time = $1 WHERE id = $2`, pickupTime, order.ID)
    return err
}

// retrieve
func (pg Postgres) GetOrder(orderID DatabaseID) (*Order, error) {
    pgOrder := PgOrder{}
    err := pg.Get(&pgOrder, `SELECT * FROM orders WHERE id = $1`, orderID)
    if err == sql.ErrNoRows {
        return nil, nil
    }
    ... // at this point pgOrder.PickupTime is 0001-01-01 00:00:00 +0000 UTC

}

如果我在更新和检索之间设置了断点,我可以检查数据库并看到一个值被保存为2017-04-20 12:05:37-04。所以问题必须在检索部分。如果我从docs理解,sqlx应该能够处理嵌入式结构。

2 个答案:

答案 0 :(得分:2)

看起来你正在影响PickupTime。如果我正在读sqlx文档,那意味着它会将值存储在它找到的第一个(按顺序)中,然后当你在PgOrder中读取它时,它是一个未初始化的time.Time。您可以检查PgOrder.PickupTime的有效字段以确认这一点(它应该无效)。

答案 1 :(得分:1)

如果您的字段是指向某个内容的指针,例如*time.Time*string您不应该使用NullXxx类型。当你有一个非零字段时,可以使用这些类型,例如: time.Timestring,而相应的列可以是NULL

如果你想要消除你的类型,为了避免@Dmitri Goldring已经提到的潜在阴影,你可以告诉sqlx跳过你不希望它扫描列的字段。就像使用json标记一样,您可以使用db标记执行此操作:

type Order struct {
    ...
    PickupTime *time.Time `json:"-" db:"-"`
}

type PgOrder struct {
    Order
    PickupTime pq.NullTime
}