Redshift возвращает [] uint8 вместо целого числа, преобразование между ними возвращает неверные значения - PullRequest
0 голосов
/ 04 марта 2019

У меня есть служба, которая принимает запрос SQL, выполняет запрос в Amazon Redshift, используя драйверы базы данных / sql.Тем не менее, я не могу преобразовать результат в структуру, потому что запросы - это задачи с большими данными для различных таблиц, не созданные в этом сервисе.Поэтому я должен вернуть «свободную» структуру данных.Я анализирую данные, возвращенные в JSON, и сохраняю их в S3.

Однако у меня возникают некоторые странные проблемы с возвращаемыми типами данных.Запросы для числовых столбцов возвращают карту uint8 вместо числового значения.Я понимаю, что это потому, что драйвер базы данных не может иметь мнения о том, во что его конвертировать, потому что он может быть неточным.Но я не могу конвертировать между [] uint8 и целым числом.

Вот мой код, который запрашивает базу данных:

// Execute executes SQL commands
func (r *Runner) Execute(query string, args ...interface{}) (types.Results, error) {
    var results types.Results
    rows, err := r.db.Query(query, args...)
    if err != nil {
        return results, err
    }

    columns, _ := rows.Columns()
    colNum := len(columns)

    values := make([]interface{}, colNum)
    for i := range values {
        var ii interface{}
        values[i] = &ii
    }

    for rows.Next() {
        rows.Scan(values...)
        result := make(types.Result)
        for i, colName := range columns {
            rawValue := *(values[i].(*interface{}))
            if reflect.TypeOf(rawValue).String() == "[]uint8" {
                byteVal := rawValue.([]byte)
                val := Intfrombytes(byteVal)
                log.Println("Converted:", val)
            }
            result[colName] = rawValue
        }
        results = append(results, result)
    }
    return results, nil
}

Я создал следующую функцию, чтобы попытаться преобразовать между []uint8 и uint32.

func Intfrombytes(bytes []uint8) uint16 {
    bits := binary.LittleEndian.Uint16(bytes)
    return bits
}

Однако, если я вставлю 200 в эту таблицу, я вернусь 12339.Подход, как правило, довольно ненадежный.Я сомневаюсь в своем решении использовать Go для этого, поскольку я имею дело с неопределенными, незакрепленными структурами данных.

Есть ли лучший подход к общим запросам, таким как мой пример, или есть способ, которым я могу преобразоватьмои числовые результаты в целое число?

1 Ответ

0 голосов
/ 04 марта 2019

Я думаю, что вы можете интерпретировать строку ([] uint8 == [] байт), на самом деле.См. https://play.golang.org/p/Rfpey2NPiI7

originalValue := []uint8{0x32, 0x30, 0x30} // "200"
bValue := []byte(originalValue) // byte is a uint8 anyway
fmt.Printf("Converted to uint16: %d\n", binary.LittleEndian.Uint16(bValue))
fmt.Printf("Actual value: %s", string(bValue))

Это укусило меня раньше, когда я имел дело с pq и некоторым криптографическим кодом.

...