2

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

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

我想把它保存到数据库中,sqlx所以我想我需要按照这里pq.NullTime的建议使用。

而不是更新Order对象(我不想将数据库代码泄漏到模型层),我想我可以将 Order 嵌入 aPgOrder并更改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. 所以问题一定出在检索部分。如果我从文档中理解正确,则 sqlx 应该能够处理嵌入式结构。

4

2 回答 2

2

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

于 2017-04-22T03:27:13.973 回答
1

如果您的字段是指向某物的指针,例如*time.Time,或者*string您不需要使用这些NullXxx类型。当您有一个非零字段时,将使用这些类型,例如time.Time,或者string它的对应列可以是NULL

如果您仍然想使用您的类型,以避免@Dmitri Goldring 已经提到的潜在阴影,您可以告诉sqlx跳过您不希望它扫描列的字段。所以就像你对json标签所做的那样,你可以对db标签这样做:

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

type PgOrder struct {
    Order
    PickupTime pq.NullTime
}
于 2017-04-22T07:54:02.650 回答