0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語でCSVファイルからデータベースにデータを挿入する方法を徹底解説

Last updated at Posted at 2024-12-24

はじめに

Go言語を使ってCSVファイルからデータを読み込み、データベースに挿入する方法を解説します。この記事では、GinフレームワークとEnt ORMを使用して、CSVファイルのデータをPostgreSQLデータベースに保存する手順を紹介します。

なお、こちらは以下の記事の続きです。

ディレクトリとCSVファイルの作成

mkdir data

このdataディレクトリになかに、csvファイルを作成します。

data/newspapers.csv
毎日新聞,余録
東京新聞,筆洗

初期データ挿入の記述

main.goを以下のようにします。

main.go
package main

import (
	"github.com/gin-gonic/gin"
	"context"
	"encoding/csv"
	"log"
	"os"
	"github.com/joho/godotenv"
	"github.com/jijimama/newspaper-app/ent"
	_ "github.com/lib/pq"
)

func main() {
	router := gin.Default()

	// .envファイルを読み込む
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env file: %v", err)
	}

	// 環境変数から取得
	dbHost := os.Getenv("DB_HOST")
	dbPort := os.Getenv("DB_PORT")
	dbUser := os.Getenv("DB_USER")
	dbName := os.Getenv("DB_NAME")
	dbPassword := os.Getenv("DB_PASSWORD")

	// 接続文字列を作成
	dsn := "host=" + dbHost + " port=" + dbPort + " user=" + dbUser + " dbname=" + dbName + " password=" + dbPassword + " sslmode=disable"

    //PostgreSQLに接続
	client, err := ent.Open("postgres", dsn)
	if err != nil {
		log.Fatalf("failed opening connection to postgres: %v", err)
	}
	defer client.Close()
	// Run the auto migration tool.
	if err := client.Schema.Create(context.Background()); err != nil {
		log.Fatalf("failed creating schema resources: %v", err)
	}

	// CSVファイルからデータを読み込み、データベースに挿入
    err = loadCSVData(client, "data/newspapers.csv")
    if err != nil {
        log.Fatalf("failed loading CSV data: %v", err)
    }
	
  	router.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
      		"message": "Hello, World!",
		})
  	})

  	router.Run(":8080")
}

func loadCSVData(client *ent.Client, filePath string) error {
    file, err := os.Open(filePath)
    if err != nil {
        return err
    }
    defer file.Close()

    reader := csv.NewReader(file)
    records, err := reader.ReadAll()
    if err != nil {
        return err
    }

    for _, record := range records {
        name := record[0]
        columnName := record[1]

        _, err := client.Newspaper.
            Create().
            SetName(name).
            SetColumnName(columnName).
            Save(context.Background())
        if err != nil {
            return err
        }
    }

    return nil
}

補足説明

reader := csv.NewReader(file)

NewReader 関数

func NewReader(r io . Reader ) * Reader
  • NewReader は、r から読み取る新しい Reader を返します。

records, err := reader.ReadAll()

(*Reader) ReadAll関数

func (r * Reader ) ReadAll() (records [][] string , err error )```
  • ReadAll は、r から残りのすべてのレコードを読み取ります。各レコードはフィールドのスライスです。呼び出しが成功すると、 err == io.EOFではなく、 err == nil が返されます。ReadAllEOF まで読み取るように定義されているため、ファイルの終わりを報告すべきエラーとして扱いません。

もう一度再起動して、データを挿入します

docker-compose up backend -d

データの確認

コンテナに入り直接確認していきます。

docker compose exec db bash
psql -U postgres -d db

db=# SELECT * FROM newspapers;
 id |   name    | column_name |          created_at           |          updated_at           
----+-----------+-------------+-------------------------------+-------------------------------
  1 |  毎日新聞 | 余録        | 2024-12-24 02:23:23.075128+00 | 2024-12-24 02:23:23.075129+00
  2 |  東京新聞 | 筆洗        | 2024-12-24 02:23:23.076488+00 | 2024-12-24 02:23:23.076488+00
(2 rows)

このように表示されれば、OKです!

参考文献

ent CRUD API
csv パッケージ NewReader関数
csv パッケージ ReadAll関数

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?