5

I am new in Golang,

  • I have csv file which have data looks like this
field1,field2
1.1,2
1.2,3
1.3,2
  • i want to insert all csv data into db table using golang without using for loop .. i am using postgres database

also don't want to use sql raw query

i am using gorm ORM

12
  • 4
    Can you show what you've tried so far? What loop specifically are you trying to avoid? The loop reading the csv records, the loop inserting the individual records? Can you show what data structure you're using to represent the csv data in Go? Commented Mar 24, 2021 at 10:49
  • yes i don't want to loop through csv records Commented Mar 24, 2021 at 10:53
  • 1
    If not SQL, what do you want to use then? Are you using some ORM? Commented Mar 24, 2021 at 11:04
  • 1
    Standard golang executes raw SQL to insert records into a database. Commented Mar 24, 2021 at 11:06
  • 2
    As mentioned, use batch insert, then. Commented Mar 24, 2021 at 11:54

2 Answers 2

12
+50

You can use pgx library for that:

    filename := "foo.csv"
    dbconn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
    if err != nil {
        panic(err)
    }
    defer dbconn.Release()
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer func() { _ = f.Close() }()
    res, err := dbconn.Conn().PgConn().CopyFrom(context.Background(), f, "COPY csv_test FROM STDIN (FORMAT csv)")
    if err != nil {
        panic(err)
    }
    fmt.Print(res.RowsAffected())
Sign up to request clarification or add additional context in comments.

4 Comments

Not sure if its due to me using pgx/v4 but this doesn't compile. This part doesn't: dbconn.Conn().PgConn().CopyFrom Which pgx version should be used?
Try to use this approach stackoverflow.com/a/68749440/1109280
Thanks! That was my post, figured it out from you did. I had to specifically use v1 of pgx instead of the latest v4. Thanks @Pavlo Golub
Oh, I see. I use v4 for sure. But maybe I have misprint in my code example since I was extracting it from the working project. You may find it here: github.com/cybertec-postgresql/pg_timetable/blob/master/…
2

You can parse the CSV into a slice of typed structures using an external library, and then insert them all at once using GORM's batch insert.

Here is an example :

import (
    "os"

    "github.com/gocarina/gocsv"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

// Entry defines both the CSV layout and database schema
type Entry struct {
    gorm.Model

    Field1 float64 `csv:"field1"`
    Field2 float64 `csv:"field2"`
}

func main() {
    // Open the CSV file for reading
    file, err := os.Open("data.csv")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // Parse CSV into a slice of typed data `[]Entry` (just like json.Unmarshal() does)
    // The builtin package `encoding/csv` does not support unmarshaling into a struct
    // so you need to use an external library to avoid writing for-loops.
    var entries []Entry
    err = gocsv.Unmarshal(file, &entries)
    if err != nil {
        panic(err)
    }

    // Open a postgres database connection using GORM
    db, err := gorm.Open(postgres.Open("host=localhost user=postgres password=dev dbname=foo port=5432 sslmode=disable TimeZone=Europe/Paris"))
    if err != nil {
        panic(err)
    }

    // Create `entries` table if not exists
    err = db.AutoMigrate(&Entry{})
    if err != nil {
        panic(err)
    }

    // Save all the records at once in the database
    result := db.Create(entries)
    if result.Error != nil {
        panic(result.Error)
    }
}

4 Comments

I'm trying to avoid defining schema. I want to be able to export data and just re import without having to deal with schema in between.
This solution will consume a lot of memory.
This solution may be used with batches.
what about files with 10Gb size?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.