Populando base MySQL com dados fake

Precisei popular uma base de dados com informações falsas, para realizar alguns testes e já que estou trabalhando com Go, resolvi automatizar o processo.

Para isso utilizei o GORM como ORM e a biblioteca Faker.

Segue abaixo o passo a passo e no final o código completo.

Definindo as variáveis com as informações básicas para rodar o projeto.

const (
	dbUser              string = "root"
	dbPass              string = "root"
	dbHost              string = "localhost"
	dbPort              string = "3306"
	dbDatabase          string = "fake_data"
	quantidadeRegistros int    = 10
)

Criar uma struct com os dados da tabela (Model).

type Pessoa struct {
	gorm.Model
	Nome  string `faker:"name"`
	Idade int
}

Observe a tag `faker` ao lado do tipo de dado.
Ela quem define o tipo de dado que será gerado.
No caso de int, ele detecta automaticamente.

Realizando a conexão com o banco de dados.

Antes de iniciar a conexão com o mysql, precisamos definir a string de conexão.
Para isso serão utilizadas as constantes definidas no início do projeto.

dsn := dbUser + ":" + dbPass + "@tcp(" + dbHost + ":" + dbPort + ")/" + dbDatabase + "?charset=utf8mb4&parseTime=True"

Com os dados definidos, iniciamos a conexão.

sqlDB, _ := sql.Open("mysql", dsn)

É passado para a conexão uma configuração referente ao Log, para não exibir as informações.

newLogger := logger.New(
	log.New(os.Stdout, "\r\n", log.LstdFlags),
	logger.Config{
		SlowThreshold:             time.Second,
		LogLevel:                  logger.Silent,
		IgnoreRecordNotFoundError: true,
		Colorful:                  false,
	},
)

Finalizamos com a conexão aberta com as configurações desejadas.

db, _ := gorm.Open(mysql.New(mysql.Config{
	Conn: sqlDB,
}), &gorm.Config{
	SkipDefaultTransaction: true,
	Logger:                 newLogger,
})

Observe que foi passado o parâmetro SkipDefaultTransaction, que desativa as transactions para otimizar o processo de inserção.

Executando a migração

Opcionalmente você pode gerar a criação da tabela a partir do Model.

db.AutoMigrate(&Pessoa{})

Gerando o dado fake para o Model.

pessoaFake := Pessoa{}
faker.FakeData(&pessoaFake)

Criando o registro no banco de dados

db.Create(&Pessoa{
	Nome:  pessoaFake.Nome,
	Idade: pessoaFake.Idade,
})

Inserimos a criação dos dados num loop e adicionamos um print com o indice do registro que está inserindo.

for i := 0; i < quantidadeRegistros; i++ {
	println("Cadastrando registro:", i+1)
	pessoaFake := Pessoa{}
	faker.FakeData(&pessoaFake)
	db.Create(&Pessoa{
		Nome:  pessoaFake.Nome,
		Idade: pessoaFake.Idade,
	})
}

Exibindo a quantidade total de registros no banco de dados.

var count int64
db.Model(&Pessoa{}).Count(&count)
println("Quantidade total de registros:", count)

Exibindo o tempo de execução do programa.

start := time.Now()
....
tempoExecucao := time.Since(start)
fmt.Printf("Tempo de execução: %s \n", tempoExecucao)

Código completo

package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/go-faker/faker/v4"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

const (
	dbUser              string = "root"
	dbPass              string = "root"
	dbHost              string = "localhost"
	dbPort              string = "3306"
	dbDatabase          string = "fake_data"
	quantidadeRegistros int    = 10
)

type Pessoa struct {
	gorm.Model
	Nome  string `faker:"name"`
	Idade int
}

func main() {
	start := time.Now()
	dsn := dbUser + ":" + dbPass + "@tcp(" + dbHost + ":" + dbPort + ")/" + dbDatabase + "?charset=utf8mb4&parseTime=True"

	sqlDB, _ := sql.Open("mysql", dsn)

	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),
		logger.Config{
			SlowThreshold:             time.Second,
			LogLevel:                  logger.Silent,
			IgnoreRecordNotFoundError: true,
			Colorful:                  false,
		},
	)

	db, _ := gorm.Open(mysql.New(mysql.Config{
		Conn: sqlDB,
	}), &gorm.Config{
		SkipDefaultTransaction: true,
		Logger:                 newLogger,
	})

	db.AutoMigrate(&Pessoa{})

	for i := 0; i < quantidadeRegistros; i++ {
		println("Cadastrando registro:", i+1)
		pessoaFake := Pessoa{}
		faker.FakeData(&pessoaFake)
		db.Create(&Pessoa{
			Nome:  pessoaFake.Nome,
			Idade: pessoaFake.Idade,
		})
	}

	var count int64
	db.Model(&Pessoa{}).Count(&count)
	println("Quantidade total de registros:", count)

	tempoExecucao := time.Since(start)
	fmt.Printf("Tempo de execução: %s \n", tempoExecucao)
}