#postgresql #go #sql-null
#postgresql #Вперед #sql-null
Вопрос:
В Go я разархивирую / декодирую JSON в структуру с полем ID типа int . Затем я пытаюсь вставить эту структуру в базу данных PostgreSQL, используя go-pg со столбцом ID в качестве первичного ключа (который имеет ограничение not-null). Первая запись имеет a 0
в качестве идентификатора. В документации Postgres указано, что 0
это нормально как значение первичного ключа. Тем не менее, я продолжаю получать сообщение об ошибке:
«ОШИБКА # 23502 нулевое значение в столбце «number» нарушает ограничение not-null».
Похоже 0
, что значение превращается в «нулевое значение», когда оно отменяется в значение int. Затем оно вставляется как null
значение в Postgres. Любые советы о том, как я мог бы избежать этого, были бы весьма признательны.
type Account struct {
Number int `sql:"type:smallint, pk"`
Name string
}
[...]
account := Account{}
err := json.NewDecoder(r.Body).Decode(amp;account)
[...]
insertErr := pgLayer.db.Insert(amp;account)
if insertErr != nil {
log.Printf("Error while inserting new item")
return "n/a", insertErr
}
Комментарии:
1. Вы пробовали
sql:"smallint,pk,notnull"
?
Ответ №1:
Хотя это не сразу очевидно, go-pg
вы можете использовать тег struct sql:",notnull"
, чтобы показать, что пустые значения Go ( ""
, 0
, []
и т.д.) разрешены и не должны рассматриваться как SQL . NULL
Вы можете увидеть это в списке функций.
В вашем случае я бы изменил это на:
type Account struct {
Number int `sql:"type:smallint,pk,notnull"`
Name string
}
Комментарии:
1. Это то, чего нам следует избегать при написании библиотек. Это приводит к наложению определенного стиля кодирования. На любом другом языке 0 — это просто ноль, и он не интерпретируется как NULL .
2. Начиная с версии 9, вы должны использовать
pg:",use_zero"
для достижения того же.
Ответ №2:
Я думаю, что самое простое решение вашей проблемы — сделать ваш ID
столбец type SERIAL
и позволить Postgres устанавливать и автоматически увеличивать значение для вас. Если вам нужно значение в вашем приложении непосредственно после его вставки, вы всегда можете использовать RETURNING
предложение psql, например:
INSERT INTO shows(
user_id, name, description, created, modified
) VALUES(
:user_id, :name, :created, :modified
) RETURNING id;
И зафиксируйте ответ в вашем коде.