Я хочу написать программу Go для выгрузки строк из таблицы базы данных в CSV файл с помощью SELECT *
.
Go предоставляет отличные sql и csv apis, но csv
ожидает массивы строк, а метод Scan
in Rows
"заполняет" поля в соответствии с их типами. Поскольку я не знаю таблицу раньше, я понятия не имею, сколько столбцов и каков их тип.
Это моя первая программа на Go, поэтому я немного борюсь.
Как мне лучше всего прочитать столбцы из экземпляра Rows
в []string
- и это "правильный" способ?
Спасибо!
ОБНОВИТЬ
Я все еще борюсь с параметрами. Это мой код, сейчас я использую panic
вместо того, чтобы возвращать error
, но я собираюсь изменить это позже. В моем тесте я os.Stdout
результат запроса и os.Stdout
.
func dumpTable(rows *sql.Rows, out io.Writer) error {
colNames, err := rows.Columns()
if err != nil {
panic(err)
}
if rows.Next() {
writer := csv.NewWriter(out)
writer.Comma = '\t'
cols := make([]string, len(colNames))
processRow := func() {
err := rows.Scan(cols...)
if err != nil {
panic(err)
}
writer.Write(cols)
}
processRow()
for rows.Next() {
processRow()
}
writer.Flush()
}
return nil
}
Для этого я не cannot use cols (type []string) as type []interface {} in function argument
(в writer.Write(cols)
.
Я тогда проверил
readCols := make([]interface{}, len(colNames))
writeCols := make([]string, len(colNames))
processRow := func() {
err := rows.Scan(readCols...)
if err != nil {
panic(err)
}
// ... CONVERSION?
writer.Write(writeCols)
}
что приводит к panic: sql: Scan error on column index 0: destination not a pointer
.
ОБНОВЛЕНИЕ 2
Я самостоятельно пришел к решению ANisus. Это код, который я использую сейчас.
func dumpTable(rows *sql.Rows, out io.Writer) error {
colNames, err := rows.Columns()
if err != nil {
panic(err)
}
writer := csv.NewWriter(out)
writer.Comma = '\t'
readCols := make([]interface{}, len(colNames))
writeCols := make([]string, len(colNames))
for i, _ := range writeCols {
readCols[i] = &writeCols[i]
}
for rows.Next() {
err := rows.Scan(readCols...)
if err != nil {
panic(err)
}
writer.Write(writeCols)
}
if err = rows.Err(); err != nil {
panic(err)
}
writer.Flush()
return nil
}