Connecting Golang with PostgreSQL and Using It with Tableau

JatinJatin
4 min read

In this blog post, we'll explore how to connect a Go application with a PostgreSQL database and visualize the data using Tableau. We'll cover best practices, a recommended folder structure, and provide step-by-step instructions to set up everything you need.

Prerequisites

  • Basic knowledge of Go (Golang).

  • PostgreSQL installed locally or access to a PostgreSQL server.

  • Tableau installed on your machine.

Step 1: Set Up Your Go Project

First, create a new directory for your project and initialize a Go module:

mkdir your-project
cd your-project
go mod init your-module-name

A well-organized folder structure is essential for maintainability. Here’s a recommended structure for your project:

your-project/
├── cmd/
│   └── your-app/
│       └── main.go          # Entry point of your application
├── internal/
│   ├── config/
│   │   └── config.go        # Configuration handling
│   ├── db/
│   │   └── db.go            # Database connection logic
│   └── models/
│       └── user.go          # Data models
├── pkg/
│   └── repository/
│       └── user_repository.go  # Repository pattern for data access
├── .env                      # Environment variables
├── go.mod                    # Go module file
└── go.sum                    # Go dependencies file

Step 2: Set Up PostgreSQL

  1. Install PostgreSQL: Make sure PostgreSQL is installed on your machine or use a cloud service.

  2. Create a Database: Create a database and a user with appropriate permissions.

Step 3: Install Required Packages

We will use the following packages in our Go application:

  • pgx: A PostgreSQL driver for Go.

  • godotenv: For loading environment variables from a .env file.

Install them using the following command:

go get github.com/jackc/pgx/v4
go get github.com/joho/godotenv

Step 4: Create Configuration Management

In internal/config/config.go, create a function to load your database configuration:


import (
    "github.com/joho/godotenv"
    "log"
    "os"
)

type Config struct {
    DBHost     string
    DBPort     string
    DBUser     string
    DBPassword string
    DBName     string
}

func LoadConfig() *Config {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    return &Config{
        DBHost:     os.Getenv("DB_HOST"),
        DBPort:     os.Getenv("DB_PORT"),
        DBUser:     os.Getenv("DB_USER"),
        DBPassword: os.Getenv("DB_PASSWORD"),
        DBName:     os.Getenv("DB_NAME"),
    }
}

Step 5: Set Up Database Connection

In internal/db/db.go, implement the logic to connect to PostgreSQL:

package db

import (
    "context"
    "fmt"
    "github.com/jackc/pgx/v4"
    "log"
    "your-module-name/internal/config"
)

func ConnectDB(cfg *config.Config) *pgx.Conn {
    conn, err := pgx.Connect(context.Background(), fmt.Sprintf(
        "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
        cfg.DBHost, cfg.DBPort, cfg.DBUser, cfg.DBPassword, cfg.DBName,
    ))

    if err != nil {
        log.Fatalf("Unable to connect to database: %v\n", err)
    }

    log.Println("Connected to PostgreSQL database!")
    return conn
}

Step 6: Define Your Models

In internal/models/user.go, define your data model:

package models

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

Step 7: Implement Repository Pattern

In pkg/repository/user_repository.go, implement the repository pattern for data access:

package repository

import (
    "context"
    "your-module-name/internal/models"
    "github.com/jackc/pgx/v4"
)

type UserRepository struct {
    db *pgx.Conn
}

func NewUserRepository(db *pgx.Conn) *UserRepository {
    return &UserRepository{db: db}
}

func (r *UserRepository) CreateUser(ctx context.Context, user *models.User) error {
    _, err := r.db.Exec(ctx, "INSERT INTO users (name, email) VALUES ($1, $2)", user.Name, user.Email)
    return err
}

// Add more repository methods as needed

Step 8: Entry Point

In cmd/your-app/main.go, set up the main function:

package main

import (
    "context"
    "your-module-name/internal/config"
    "your-module-name/internal/db"
    "your-module-name/pkg/repository"
)

func main() {
    cfg := config.LoadConfig()
    conn := db.ConnectDB(cfg)
    userRepo := repository.NewUserRepository(conn)

    // Example usage
    ctx := context.Background()
    user := &models.User{Name: "John Doe", Email: "john@example.com"}
    if err := userRepo.CreateUser(ctx, user); err != nil {
        log.Fatalf("Error creating user: %v\n", err)
    }
}

Step 9: Connecting to Tableau

  1. Open Tableau and select PostgreSQL as your data source.

  2. Enter your PostgreSQL server credentials (host, port, database, username, password).

  3. Drag and drop your tables into the Tableau workspace to visualize your data.

Best Practices

  • Environment Configuration: Store sensitive information (like database credentials) in a .env file.

  • Repository Pattern: Encapsulate database access to improve maintainability and testability.

  • Error Handling: Implement comprehensive error handling throughout your application.

  • Logging: Use a logging library for better log management.

  • Testing: Write unit tests for your repository methods and other critical functions.

Conclusion

By following the steps outlined in this post, you can successfully connect a Go application to a PostgreSQL database and visualize your data using Tableau. This approach not only improves your application's maintainability but also adheres to best practices in software development. Happy coding!

1
Subscribe to my newsletter

Read articles from Jatin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jatin
Jatin