Objetivo principal:
Implementar las operaciones básicas sobre una base de datos relacional empleando una base de datos ejecutandose en un contenedor.
Objetivos especificos:
- Crear contenedor Docker con Postgres
- Conectarse a la base de datos en Docker
- Implementar adición de datos (Create)
- Implementar consulta de datos (Read)
- Implementar actualización de datos (Update)
- Implementar eliminación de datos (Delete)
Introduccion:
Se inicia con un modelo de tablas que describe la aridad y se empelará para crear los modelos implementados mediante la librería GORM (Go Object Relational Mapping) y una base de datos relacional, para este ejemplo PostgreSQL.
Descripcion del problema:
Se requiere registrar la informacion de los clientes y los pedidos que realizan.
Preparacion.
Se crea carpeta de trabajo pedidos_test y dentro de ella se crea la carpeta /app. Además creamos los archivos para de soporte del proyecto .gitignore, Makefile, docker-compose.yml, .env y README.md.
Luego iniciamos el repositorio git y con eso completamos la estructura del proyecto.
Base de datos.
Si bien es mas fácil trabajar con una base de datos mas sencilla como sqlite, se implmentará un contenedor que nos permitirá a futuro emplear este proyecto base para crear otros proyectos y abordar diferentes enfoques.
Este es un codigo basico del contenedor que ejecuta el servidor postgres, que se encuentra en el archivo docker-compose.yml.
volumes:
pg-pedidos:
services:
postgres-pedidos-service:
image: postgres:16
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "5432:5432"
volumes:
- pg-pedidos:/var/lib/postgresql/data
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}" ]
interval: 10s
timeout: 5s
retries: 6
restart: unless-stopped
El archivo Makefile puede inicializarse desde ahora pero mas adelante será modificado para gestionar la compilación de la aplicación en Go. Este es el archivo Makefile inicial.
up:
@echo "Iniciando imagen docker.."
docker compose up -d
@echo "Imagenes docker iniciadas!"
down:
@echo "Deteniendo imagenes docker"
docker compose down
@echo "Hecho!"
Esto nos ayudará a gestionar facilmente el codigo y el contenedor en la medida en que progresamos o complejizamos nuestros códigos.
Se deben agregar finalmente las credenciales, las cuales estarán en el archivo .env, estas serán requeridas en varias instacias del ejercicio.
DB_HOST=localhost
DB_PORT=5432
DB_USER=adminapp
DB_PASSWORD=verysecret
DB_NAME=pedidos
Con esto pasamos a probar la ejecución del contenedor y la base de datos, para ello en la terminal ejecutamos el comando make up, el cual levnata el servicio.
Se puede observar que el servidor se ejecuta (uso podman desktop para observarlo mediante una interfaz grafica) y se verifica que esta corriendo.
Aplicacion en Go
A continuación me posiciono en la carpeta app e inicializo el proyecto en go y creo el archivo principal
go mod init add_pedidos
touch main.go
Lo siguiente es importar las librerias de GORM necesarias, la librería GORM y el manejadores (driver) de postgres y la librería necesaria para leer las variables de entorno.
go get -u gorm.io/gorm \
go get -u gorm.io/driver/postgres \
go get -u github.com/joho/godotenv
Se puede encontrar en la documentacion del paquete gorm los manejadores para diversas bases de datos.
Se debe crear una carpeta que contendrá la definicion de las tablas (modelo de datos) llamada modelo_app.go y la carpeta /db que contendra el codigo de conexion con la base de datos dblib_pg.go.
package models
import (
"time"
"gorm.io/gorm"
)
type Cliente struct {
Nombre1 string // Cadena obligatoria
Nombre2 *string // Cadena que puede ser vacia
Apellido1 string // Cadena obligatoria
Apellido2 *string // Cadena que puede ser vacia
TipoDocumento string // Cadena obligatoria
Documento string `gorm:"primaryKey;not null"`
CreatedAt time.Time // Gestionada automaticamente por GORM al crear registro
UpdatedAt time.Time // Gestionada automaticamente por GORM al actualizar registro
Enabled bool // Indicador de registro activo
Contactos []Contacto `gorm:"foreignkey:ClienteDoc;references:Documento"`
}
type Contacto struct {
gorm.Model
TipoDato string // Tipo de registro, puede ser correo, telefono, etc
Dato string // El valor registrado
CreatedAt time.Time // Gestionada automaticamente por GORM al crear registro
UpdatedAt time.Time // Gestionada automaticamente por GORM al actualizar registro
Enabled bool // Indicador de registro activo
ClienteDoc string //llave foranea IDCliente
}
package db
import (
"fmt"
"os"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var Database *gorm.DB
func Connect() {
var err error
dbHost := os.Getenv("DB_HOST")
dbPuerto := os.Getenv("DB_PORT")
dbUsuario := os.Getenv("DB_USER")
dbPw := os.Getenv("DB_PASSWORD")
dbNombre := os.Getenv("DB_NAME")
fmt.Println("Conectando con " + dbHost + ":" + dbPuerto)
dsn := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable", dbUsuario, dbPw, dbHost, dbPuerto, dbNombre)
Database, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Printf("Error en conexion a la base de datos")
panic(err)
} else {
fmt.Println("Conexion con base de datos exitosa!")
}
}
Finalmente se integra desde el programa principal main.go la conexion a la base de datos, la creacion de las tablas y la prueba de registro de datos.
package main
import (
"app_pedidos/db"
"app_pedidos/models"
"context"
"log"
"github.com/joho/godotenv"
"gorm.io/gorm"
)
func main() {
loadEnv()
db.Connect()
db.Database.AutoMigrate(&models.Cliente{})
db.Database.AutoMigrate(&models.Contacto{})
NuevoCliente()
NuevoContacto()
}
func loadEnv() {
err := godotenv.Load("../.env")
if err != nil {
log.Fatal("Error encontrando .env file")
}
}
func NuevoCliente() {
cliente := models.Cliente{
Nombre1: "Juan",
Apellido1: "Perez",
TipoDocumento: "DNI",
Documento: "2012",
}
ctx := context.Background()
err := gorm.G[models.Cliente](db.Database).Create(ctx, &cliente)
if err != nil {
panic(err)
} else {
log.Println("Cliente creado correctamente")
}
}
func NuevoContacto() {
contacto := models.Contacto{
TipoDato: "correo",
Dato: "jaun@test.com",
ClienteDoc: "2012",
}
ctx := context.Background()
err := gorm.G[models.Contacto](db.Database).Create(ctx, &contacto)
if err != nil {
panic(err)
} else {
log.Println("Contacto creado correctamente")
}
}
Ejecutar codigo del programa
Se debe ir a la carpeta /app y alli ejecutar el programa principal con el comando go run main.go
Esto crea la conexion a la base de datos, crea las tablas y adiciona registros basicos de clientes y contactos.
Se puede observar que en la base de datos han quedado registrados los valores del ejemplo.
Este es un ejemplo basico de implmenetacion, en la segunda parte se completará el ejercicio completando la actualización y la consulta de registros.
Hasta pronto!








Top comments (0)