Golang Postgres константы ошибок?

Я пытаюсь удалить базу данных с помощью драйвера postgres (lib/pq), выполнив:

db.Exec("DROP DATABASE dbName;")

Но я хотел бы сделать другое условие, основанное на том, является ли полученная ошибка чем-то странным или ошибка "базы данных не существует".

Мой вопрос: есть ли постоянная переменная или что-то, что я могу использовать, чтобы проверить, является ли возвращенная ошибка сообщением об ошибке "база данных не существует", или мне придется самому анализировать строку ошибки самостоятельно?

Я пытался заглянуть в документацию, но не смог найти ничего для "базы данных не существует". Однако я нашел этот список: https://www.postgresql.org/docs/9.3/static/errcodes-appendix.html

Возможно, он подходит под другой код ошибки? Также я не совсем уверен в семантически правильном способе извлечения и сравнения кодов ошибок через драйвер Postgres. Я полагаю, я должен сделать что-то вроде этого?

if err.ErrorCode != "xxx"

Спасибо.

3 ответа

Решение

lib/pq пакет может возвращать ошибки типа *pq.Error, который является структурой. Если это так, вы можете использовать все его поля для проверки деталей ошибки.

Вот как это можно сделать:

if err, ok := err.(*pq.Error); ok {
    // Here err is of type *pq.Error, you may inspect all its fields, e.g.:
    fmt.Println("pq error:", err.Code.Name())
}

pq.Error имеет следующие поля:

type Error struct {
    Severity         string
    Code             ErrorCode
    Message          string
    Detail           string
    Hint             string
    Position         string
    InternalPosition string
    InternalQuery    string
    Where            string
    Schema           string
    Table            string
    Column           string
    DataTypeName     string
    Constraint       string
    File             string
    Line             string
    Routine          string
}

Значение и возможные значения этих полей зависят от Postres, а полный список можно найти здесь: Поля сообщений об ошибках и уведомления

Вы можете использовать этот https://github.com/omeid/pgerror, он имеет множество сопоставлений для различных ошибок postgres.

например, с пакетом вы можете сделать следующее, как показано в документации к пакету

      // example use:
_, err = stmt.Exec(SomeInsertStateMent, params...)
if err != nil {
  if e := pgerror.UniqueViolation(err); e != nil {
  // you can use e here to check the fields et al
    return SomeThingAlreadyExists
  }

  return err // other cases.
}

В этом пакете есть все константы ошибок PG:https://github.com/jackc/pgerrcode

Просто импортируйте, и все готово:

      import "github.com/jackc/pgerrcode"

// ...

if err, ok := err.(*pq.Error); ok {
  if err.Code == pgerrcode.UniqueViolation {
    return fmt.Errorf("unique field violation on column %s", err.Column)
  }
}

Пакет также входит в семейство одного из 2 или 3 самых популярных драйверов Go PostgreSQL, называемого «pgx», поэтому он должен быть достаточно надежным.

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