Okure U. Edet

Go es un lenguaje de programación rápido con una sintaxis relativamente simple. Mientras se está aprendiendo Go, es importante aprender cómo construir APIs y cómo utilizarlas para comunicarse con bases de datos. Durante el proceso de aprendizaje, decidí tomar un proyecto que me ayudó en esa dirección: una API de seguimiento de inventario simple.

Mientras trabajaba con una base de datos SQL como Postgres, descubrí que es importante hacer cambios en la base de datos en forma oportuna. Así que si tienes un esquema que podrás modificar en el futuro, la mejor manera de hacerlo es mediante migraciones de base de datos. Esto garantiza que los cambios en la base de datos se realizan con precisión sin afectar los datos existentes.

En este artículo, aprenderás sobre migraciones de base de datos usando Docker y Postgres.

Tabla de Contenidos

¿Qué es una migración de base de datos?

¿Qué es una migración de base de datos y por qué debería usarla? Bueno, como desarrollador backend, cuando trabaja en un proyecto que requiere almacenar datos en una base de datos, tendrá que desarrollar un esquema para los datos que desea almacenar.

Las migraciones de base de datos le ayudan a gestionar la estructura de datos dentro de una base de datos, en este caso, una base de datos relacional. Las migraciones ayudan a modificar esquemas desde un estado actual a un estado específico/deseado. Puede implicar la adición de tablas y columnas, la eliminación de elementos o el cambio de tipos y restricciones.

Una importancia de las migraciones de base de datos es hacer cambios en una base de datos repetibles y sin problemas, sin la preocupación de pérdida de datos.

Se recomienda utilizar migraciones si no está seguro de cómo se verá su esquema de datos final. En este sentido, puede implementar cambios incrementalmente.

Cómo iniciar y ejecutar un contenedor Docker

Abre tu terminal y crea un nuevo directorio mkdir tracking-inventory-app.

A continuación, extrae una imagen de postgres de Docker Hub. Utiliqué la etiqueta postgres:14-alpine. Puedes usar cualquier etiqueta que quieras.

En tu terminal, pega lo siguiente y presiona enter:

$ docker pull postgres:14-alpine

Después de instalarlo, inicie el contenedor utilizando el comando docker run:

$ docker run --name postgres14 -e POSTGRES_USER=root -e POSTGRES_PASSWORD=passwordd -p 5432:5432 -d postgres:14-alpine

La bandera --name se refiere al nombre del contenedor. La bandera -e se refiere a las variables de entorno. La bandera -p significa publicar. Debe ejecutar su contenedor en un puerto específico. La bandera -d significa que quiere ejecutarlo en modo desconectado.

Después de presionar Enter, abra su Docker Desktop si lo tiene instalado. Si no, puede descargarlo desde el sitio web de Docker.

En su Docker Desktop, debería ver que el contenedor ha sido iniciado:

Puede establecer una conexión con la base de datos utilizando TablePlus:

Pruebe la conexión. Si dice ok, entonces conéctese. Si estás en Windows y muestra un error de autenticación, vaya al botón Inicio y haga clic en Ejecutar. En el cuadro de dialogo, escriba services.msc y presione Enter. Busque postgres y haga clic en el servicio Detener. Luego intente conectarse de nuevo.

Cómo Crear y Ejecutar un Esquema Utilizando TablePlus

He creado un esquema predefinido/modelo para el proyecto tracking-inventory con db diagram. Este tracking-inventory debería permitirle agregar un elemento, número de serie y valor. Así que el esquema tendrá campos item, serial_number, id y created_at.

CREATE TABLE "inventory" (
  "id" uuid PRIMARY KEY,
  "item" varchar NOT NULL,
  "serial_number" varchar NOT NULL,
  "user" uuid NOT NULL,
  "created_at" timestamptz NOT NULL DEFAULT 'now()'
);

CREATE TABLE "user" (
  "id" uuid PRIMARY KEY,
  "name" varchar NOT NULL,
  "email" varchar UNIQUE NOT NULL,
  "password" varchar NOT NULL,
  "created_at" timestamptz NOT NULL DEFAULT 'now()'
);

CREATE INDEX ON "inventory" ("item");

ALTER TABLE "inventory" ADD FOREIGN KEY ("user") REFERENCES "user" ("id");

Este es como mi aspecto. Puede abrir su TablePlus y agregar el código de PostgreSQL generado y ejecutarlo.

Cómo instalar golang-migrate

El siguiente paso es instalar golang-migrate en tu sistema. Estoy usando Linux en Windows para este tutorial.

Para instalarlo, visita esta documentación.

Estoy usando Linux así que usaré curl:

$ curl -L https://github.com/golang-migrate/migrate/releases/download/v4.12.2/migrate.linux-amd64.tar.gz | tar xvz

Una vez instalado correctamente, en tu terminal, ejecuta el comando migrate -help para ver sus diferentes comandos.

Cómo crear una nueva migración

Después de instalar golang-migrate, puedes crear un script de migración nuevo.

Primero, en tu terminal y dentro de la carpeta tracking-app, abre VS Code con el comando code.

Una vez hecho esto, crea una nueva carpeta llamada db y otra carpeta dentro de la carpeta db llamada migrations.

A continuación, en tu terminal, ejecuta el siguiente comando:

 $ migrate create -ext sql -dir db/migration -seq tracking_inventory_schema

La opción -ext se refiere a la extensión con la que deseas que se cree la migración. En este caso, es sql. La opción -dir se refiere a la carpeta en la que deseas crear los archivos. La opción -seq se refiere al número secuencial para los archivos de migración.

En tu VS Code debería haber dos archivos: uno para up y otro para down. El primero se utiliza para hacer cambios hacia delante en el directorio mientras que el segundo se utiliza para revertir los cambios.

En el archivo up vas a pegar tu esquema al archivo.

Mi esquema se parece a esto:

CREATE TABLE "inventory" (
  "id" uuid PRIMARY KEY,
  "item" varchar NOT NULL,
  "serial_number" varchar NOT NULL,
  "user" uuid NOT NULL,
  "created_at" timestamptz NOT NULL DEFAULT 'now()'
);

CREATE TABLE "user" (
  "id" uuid PRIMARY KEY,
  "name" varchar NOT NULL,
  "email" varchar UNIQUE NOT NULL,
  "password" varchar NOT NULL,
  "created_at" timestamptz NOT NULL DEFAULT 'now()'
);

CREATE INDEX ON "inventory" ("item");

ALTER TABLE "inventory" ADD FOREIGN KEY ("user") REFERENCES "user" ("id");

El tuyo puede parecer diferente dependiendo del proyecto en el que estás construyendo.

Para el archivo down, simplemente pega esto:

DROP TABLE IF EXISTS inventory;
DROP TABLE IF EXISTS user;

Antes de cualquier cosa, debería eliminarse primero la tabla de inventario porque hace referencia a la tabla de usuarios.

Cómo Crear y Eliminar la Base de Datos dentro y fuera de un Contenedor Postgres Docker

Comprueba si tu contenedor de Docker está en ejecución usando la orden:

$ docker ps

Si no lo está, usa la orden docker start ${container name} para iniciarlo.

El siguiente paso es acceder a la consola de Postgres usando la siguiente orden, ya que estoy en Linux:

$ docker exec -it postgres14 bin/bash

La opción -it significa shell interactivo/terminal. Dentro de esta shell, puedes ejecutar la orden createdb:

/# createdb --username=root --owner=root tracking_inventory

Una vez creada, puedes ejecutar la orden psql para interactuar con la base de datos:

/# psql tracking-inventory
psql (14.12)
Type "help" for help.

tracking_inventory=#

También puedes eliminar la base de datos usando la orden dropdb.

Para salir de la shell, usa la orden exit.

Para crear la base de datos fuera del contenedor de Postgres, pega la siguiente orden:

$ docker exec -it postgres14 createdb --username=root --owner=root tracking_inventory

Cómo Visualizar la Base de Datos en TablePlus

Para visualizar la base de datos que has creado, conéctate usando la conexión previa que establecimos anteriormente. Llevará a la base de datos raíz y luego hace clic en el icono de base de datos en la parte superior.

La base de datos creada aparecerá, luego solo hace clic en open para abrirla

Cómo Ejecutar las Migraciones

Para ejecutar las migraciones, ejecuta esta orden en tu terminal:

$ migrate -path db/migration -database "postgresql://root:passwordd@localhost:5432/tracking_inventory?sslmode=disable" -verbose up

La bandera -path especifica la ruta que contiene los archivos de migración. La opción -database especifica la URL a la base de datos.

Dentro de la URL, el controlador es postgresql. El usuario y la contraseña son root y passwordd respectivamente. También es importante agregar la opción sslmode=disable porque Postgres no habilita SSL de forma predeterminada.

Ahora ejecuta las migraciones:

$ migrate -path db/migration -database "postgresql://root:passwordd@localhost:5432/tracking_inventory?sslmode=disable" -verbose up
calhost:5432/tracking_inventory?sslmode=disable" -verbose up
2024/06/25 00:13:25 Start buffering 1/u tracking_inventory_schema
2024/06/25 00:13:25 Read and execute 1/u tracking_inventory_schema
2024/06/25 00:13:26 Finished 1/u tracking_inventory_schema (read 43.186044ms, ran 255.501635ms)
2024/06/25 00:13:26 Finished after 312.928488ms
2024/06/25 00:13:26 Closing source and database

La migración ha sido exitosa!

Actualiza la base de datos y ve la nuevas tablas:

##Conclusión

A lo largo de este tutorial, has aprendido cómo escribir y ejecutar migraciones de base de datos sin problemas en Go usando Docker y Postgres. Espero que haya aprendido mucho de este artículo.

Puedes conectarte conmigo en twitter o en linkedin.