1

I have a docker container with *.csv files in it. I want to import data from that files into my postgresql database. The tables creates from schema.sql file. I need to import from 3 different csv files data into 3 different tables in my db. I tried to make it with db.Exec('COPY <table_name> FROM <path> DELIMITER ',' CSV HEADER; but it didn't work (error: cannot open file, or file doesn't exist) So i make the following function and it works fine, but i think it is not a good solution.

func AddSomeDataIntoTable(tableName, path string, fieldsQty int) error {
    file, err := os.Open(path)
    if err != nil {
        return err
    }
    defer file.Close()

    reader := csv.NewReader(file)

    if _, err := reader.Read(); err == io.EOF {
        return fmt.Errorf("error: empty file")
    }

    //loop of reading
    for i := 0; ; i++ {
        record, err := reader.Read()
        if err != nil {
            if err != io.EOF {
                return fmt.Errorf("Error reading file: %w", err)
            }
            if i == 0 {
                return fmt.Errorf("Malformed csv file: there's only headers and no values")
            } else {
                log.Print("end of file")
                //end of the file
                return nil
            }
        }

        //malformed csv handling
        if len(record) != fieldsQty {
            return fmt.Errorf("Malformed csv file: wrong number of fields")
        }
        for _, v := range record {
            if v == "" {
                return fmt.Errorf("malformed csv file: empty fields")
            }
        }
        _, err = uuid.Parse(record[0])
        if err != nil {
            return fmt.Errorf("malformed id, should be a uuid: %w", err)
        }

        switch tableName {
        case "<table_name1>":
            _, err = db.Pdb.Exec(`INSERT INTO <table_name1> (field1, field2, field3, field4, field5) VALUES ($1, $2, $3, $4, $5)`,
                record[0], record[1], record[2], record[3], record[4])
            if err != nil {
                return fmt.Errorf("internal db problems: %w", err)
            }
        case "<table_name2":
            _, err = db.Pdb.Exec(`INSERT INTO table_name2 (field1, field2) VALUES ($1, $2)`,
                record[0], record[1])
            if err != nil {
                return fmt.Errorf("internal db problems: %w", err)
            }
        case "<table_name3>":
            _, err = db.Pdb.Exec(`INSERT INTO table_name3 (field1, field2) VALUES ($1, $2)`,
                record[0], record[1])
            if err != nil {
                return fmt.Errorf("internal db problems: %w", err)
            }
        default:
            return fmt.Errorf("cannot find such table")
        }
    }

    return nil
}

May be someone can advise me any other better solution?

1oko
  • 95
  • 5

0 Answers0