Запрос целочисленного массива из PostreSQL всегда возвращает []uint8

Возьмите простую базу данных PostreSQL с целочисленным массивом:

CREATE TABLE foo (
    id                       serial PRIMARY KEY,
    bar               integer[]
);

INSERT INTO foo VALUES(DEFAULT, '{1234567, 20, 30, 40}');

Используя pq, эти значения по некоторым причинам извлекаются в виде массива []uint8.
В документации сказано, что целочисленные типы возвращаются как int64. Разве это не относится и к массивам?

db, err := sql.Open("postgres", "user=a_user password=your_pwd dbname=blah")
if err != nil {
    fmt.Println(err)
}

var ret []int
err = db.QueryRow("SELECT bar FROM foo WHERE id=$1", 1).Scan(&ret)
if err != nil {
    fmt.Println(err)
}

fmt.Println(ret)

Выход:

sql: Scan error on column index 0: unsupported Scan, storing driver.Value type []uint8 into type *[]int64
[]

2 ответа

Решение

Вы не можете использовать ломтик int как driver.Value, Аргументы Scan должен иметь один из поддерживаемых типов или реализовывать интерфейс sql.Scanner.

Причина, по которой вы видите []uint8 в сообщении об ошибке, что необработанное значение, возвращаемое из базы данных является []byte ломтик, для которого []uint8 это синоним.

Чтобы интерпретировать это []byte Для правильного среза в качестве пользовательского типа массива PostgreSQL вы должны использовать соответствующие типы массивов, определенные в пакете pq, такие как Int64Array.

Попробуйте что-то вроде этого:

var ret pq.Int64Array
err = db.QueryRow("SELECT bar FROM foo WHERE id=$1", 1).Scan(&ret)
if err != nil {
    fmt.Println(err)
}

fmt.Println(ret)

Проблема будет более серьезной, если вы используете выборку нескольких строк. Вышеприведенный код работает для одной строки, чтобы получить несколько строк, используйте это

`rows, err := db.QueryContext(ctx, stmt, courseCode)if err != nil { вернуть nil, err} отложить rows.Close()

      var feedbacks []*Feedback1

for rows.Next() {
    var feedback Feedback1
    var ret pq.Int64Array
    var ret1 pq.Int64Array
    err := rows.Scan(
        &feedback.ID,
        &ret,
        &ret1,
    )
    if err != nil {
        return nil, err
    }

    //for loop to convert int64 to int
    for i:=0;i<len(ret);i++{
        feedback.UnitFeedback = append(feedback.UnitFeedback,int(ret[i]))}

    for i:=0;i<len(ret1);i++{
        feedback.GeneralFeedback = append(feedback.GeneralFeedback,int(ret1[i]))}

    feedbacks = append(feedbacks, &feedback)
}`
Другие вопросы по тегам