Как избежать того, что 0 (ноль) int превращается в значение Postgres «null» и нарушает ограничение «not null»?

#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;
  

И зафиксируйте ответ в вашем коде.