Chcę napisać program Go, aby zrzuty wierszy z tabeli bazy danych do pliku csv przy użyciu SELECT *
.odczytać kolumny "SELECT *" na ciąg znaków [] w go
Go zapewnia doskonałe sql i csv API, ale csv
spodziewa tablic ciągów i metoda w Rows
Scan
„wypełnia” pól w zależności od ich rodzaju. Ponieważ nie znam tabeli wcześniej, nie mam pojęcia, ile kolumn jest i jakie są ich typy.
To mój pierwszy program w Go, więc trochę się zmagam.
Jak najlepiej odczytać kolumny z instancji Rows
w []string
- i czy jest to "właściwy" sposób?
Dzięki!
UPDATE
ja wciąż zmaga się z parametrami. To jest mój kod, na razie używam panic
zamiast zwracać error
, ale zamierzam to później zmienić. W moim teście przekazuję wynik zapytania i 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
}
W tym uzyskać cannot use cols (type []string) as type []interface {} in function argument
(w linii writer.Write(cols)
.
Następnie testowane
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)
}
które prowadzą do panic: sql: Scan error on column index 0: destination not a pointer
.
UPDATE 2
Niezależnie przybyłem do rozwiązania ANisus. To jest kod, którego teraz używam.
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
}
Hej, świetnie! Właśnie tam przybyłem i chciałem opublikować go w edycji. Dzięki! To będzie moja odpowiedź, a ja ją przegłosuję, ale wciąż mam pytanie: chcę, żeby to było szybkie i chciałbym uciec od wartości ciągu i przekonwertować zero do \ N. Jak najlepiej uwzględnić konwersje w moim kodzie? – Arne
Moje rozwiązanie jest dalekie od wodoszczelności. Wymaga, aby wartości mogły być przechowywane w 'ciągu'. Na przykład. jeśli otrzymasz wartość NULL z bazy danych, pojawi się błąd, ponieważ ciąg nie może mieć wartości 'nil'. Zaktualizowałem odpowiedź za pomocą bajtu [] i sprawdzając wartości 'nil'. – ANisus
Możesz rozważyć użycie 'sql.RawBytes' zamiast' [] byte' –