0

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

M_x
  • 474
  • 1
  • 15

2 Answers2

6

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())
Pavlo Golub
  • 166
  • 2
  • 7
1

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)
    }
}
Arthur Chaloin
  • 441
  • 1
  • 3
  • 11