嵌入sqlx的结构不从db返回值
Struct embedding with sqlx not returning value from db
我有一个时间字段可能为零的结构:
type Order struct {
...
PickupTime *time.Time `json:"-"`
}
我想用 sqlx
将其保存到数据库中,所以我想我需要按照建议使用 pq.NullTime
here。
不是更新 Order
对象(我不想将数据库代码泄漏到模型层),我想我可以在 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 = WHERE id = `, 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 = `, 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 应该能够处理嵌入式结构。
您似乎在跟踪 PickupTime。如果我正在正确阅读 sqlx 文档,这意味着它将把值存储在它找到的第一个(按顺序)中,然后当你在 PgOrder 中读取它时,它是一个未初始化的 time.Time。您可以检查 PgOrder.PickupTime 的 Valid 字段以确认这一点(它应该是无效的)。
如果您的字段是指向某物的指针,例如*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
}
我有一个时间字段可能为零的结构:
type Order struct {
...
PickupTime *time.Time `json:"-"`
}
我想用 sqlx
将其保存到数据库中,所以我想我需要按照建议使用 pq.NullTime
here。
不是更新 Order
对象(我不想将数据库代码泄漏到模型层),我想我可以在 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 = WHERE id = `, 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 = `, 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 应该能够处理嵌入式结构。
您似乎在跟踪 PickupTime。如果我正在正确阅读 sqlx 文档,这意味着它将把值存储在它找到的第一个(按顺序)中,然后当你在 PgOrder 中读取它时,它是一个未初始化的 time.Time。您可以检查 PgOrder.PickupTime 的 Valid 字段以确认这一点(它应该是无效的)。
如果您的字段是指向某物的指针,例如*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
}