Структурное встраивание с использованием sqlx, не возвращающего значение из БД

У меня есть структура с полем времени, которое может быть ноль:

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

Я хочу сохранить это в БД с sqlx так что я думаю, мне нужно использовать pq.NullTime как предложено здесь.

Вместо обновления Order объект (я не хочу просачивать код БД в слой модели), я подумал, что мог бы встроить порядок в PgOrder и изменить 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 должен уметь обрабатывать встроенные структуры.

2 ответа

Решение

Если ваше поле является указателем на что-то, например *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
}

Похоже, вы следите за PickupTime. Если я правильно читаю документацию sqlx, это означает, что он будет хранить значение в первом найденном им значении (в порядке), а затем, когда вы читаете значение в PgOrder, это неинициализированное время. Время. Вы можете проверить поле Valid в PgOrder.PickupTime, чтобы подтвердить это (оно должно быть недействительным).

Другие вопросы по тегам