Запрос целочисленного массива из 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)
}`