2017-05-21 2 views
0

Ich verwende go-sql-driver, um eine Verbindung zu mysql von go, und ich würde gerne einen Leser verwenden, um eine große Anzahl von Zeilen (34M +) einfügen.Verwenden von RegisterReaderHandler zum Einfügen von Zeilen in Mysql

Ich habe eine harte Zeit mit einem io.Reader, um die Daten as shown on the RegisterReaderHandler documentation zu laden.

Ich habe eine Tabelle wie folgt definiert

CREATE TABLE `test` (
    `Id` int(11) NOT NULL, 
    `One` varchar(45) DEFAULT NULL, 
    `Two` varchar(45) DEFAULT NULL, 
    `Three` varchar(45) DEFAULT NULL, 
    PRIMARY KEY (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

Und ich versuche, eine Zeile einzufügen von

func (r MyReader) Read(p []byte) (n int, err error){ 
    buf := new(bytes.Buffer) 
    wr := csv.NewWriter(buf) 

    // just generate a csv line to see if this works 
    // I've verified that the size of the result is lower than p's capacity 
    wr.Write([]string{"1", "Something", "NULL", "Something"}) 
    wr.Flush() 

    p = buf.Bytes()  
    return len(p), io.EOF 
} 

func main() { 
    mysql.RegisterReaderHandler("data", func() io.Reader { 
     // pass my reader 
     return MyReader{} 
    }) 

    db, err := sql.Open("mysql", "user:[email protected]/db") 
    checkErr(err) 

    _, err = db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE test FIELDS TERMINATED BY ','") 
    checkErr(err) 
} 

tun ich sehe, dass meine Read Operation genannt wird, und nachdem diese eine Lauf Neues Element wird erstellt. Es hat jedoch Id 0 und alle anderen Elemente sind NULL, also verarbeitet es die Daten nicht korrekt.

FWIW, Ich führe den LOAD DATA LOCAL Befehl in mysql (mit den gleichen Inhalt der Leser generiert) und die Zeile wurde erfolgreich eingefügt.

Was fehlt mir?

Antwort

0

Offensichtlich, 3 Minuten nach dem Veröffentlichen der Frage habe ich die Antwort herausgefunden.

Ich ersetzte den Ausgabepuffer in MyReader. So ändert die Linie

p = buf.Bytes() 

Mit

out = buf.Bytes() 
copy(p, out) 

hat den Trick

Verwandte Themen