Trabajo con bases de datos en Go: PostgreSQL y MongoDB
Go (Golang) es un lenguaje compilado moderno, ideal para crear servicios backend de alta carga. Una de las tareas clave de cualquier backend es trabajar con bases de datos. En este artículo, analizaremos en detalle cómo conectarse y realizar operaciones CRUD con dos de los SGBD más populares: PostgreSQL relacional y MongoDB orientado a documentos. Obtendrá ejemplos de código listos, best practices y consejos para optimizar consultas.
1. Preparación del entorno e instalación de drivers
Antes de comenzar, asegúrese de tener instalado Go versión 1.19 o superior. Para trabajar con bases de datos, necesitaremos dos paquetes principales:
- database/sql — paquete estándar de Go para trabajar con bases de datos SQL (interfaz común);
- lib/pq — driver para PostgreSQL;
- go.mongodb.org/mongo-driver — driver oficial de MongoDB.
Instalación de drivers mediante go get:
go get github.com/lib/pqgo get go.mongodb.org/mongo-driver/mongoCree un nuevo módulo para su proyecto:
mkdir go-db-examplecd go-db-examplego mod init go-db-example2. Trabajo con PostgreSQL en Go
PostgreSQL es un potente SGBD objeto-relacional. En Go, se trabaja con él a través de la interfaz database/sql.
2.1 Conexión a la base de datos
Creemos un archivo main.go y escribamos la conexión a una base de datos Postgres local:
package main
import ( "database/sql" "fmt" "log"
_ "github.com/lib/pq")
func main() { // Cadena de conexión: user password dbname sslmode connStr := "user=postgres password=mysecretpassword dbname=testdb sslmode=disable" db, err := sql.Open("postgres", connStr) if err != nil { log.Fatal("Error de conexión:", err) } defer db.Close()
// Verificamos la conexión err = db.Ping() if err != nil { log.Fatal("No se pudo conectar a la BD:", err) } fmt.Println("¡Conectado exitosamente a PostgreSQL!")}2.2 Creación de tabla e inserción de datos
Después de la conexión, creemos la tabla users e insertemos algunos registros:
// Creación de tablacreateTable := `CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, age INT);`
_, err = db.Exec(createTable)if err != nil { log.Fatal("Error al crear la tabla:", err)}
// Inserción de datosinsert := `INSERT INTO users (name, email, age) VALUES ($1, $2, $3)`_, err = db.Exec(insert, "Ana Petrova", "anna@example.com", 28)if err != nil { log.Fatal("Error al insertar:", err)}fmt.Println("Datos agregados")2.3 Lectura de datos (SELECT)
Usamos QueryRow para un solo registro y Query para múltiples:
// Obtener un solo registrovar id intvar name, email stringvar age sql.NullInt64
row := db.QueryRow("SELECT id, name, email, age FROM users WHERE email = $1", "anna@example.com")err = row.Scan(&id, &name, &email, &age)if err != nil { log.Fatal("Error al escanear:", err)}fmt.Printf("ID: %d, Nombre: %s, Email: %s, Edad: %v", id, name, email, age)
// Obtener todos los registrosrows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")if err != nil { log.Fatal("Error en la consulta:", err)}defer rows.Close()
for rows.Next() { err := rows.Scan(&id, &name, &email) if err != nil { log.Fatal("Error al leer la fila:", err) } fmt.Printf("User: %d | %s | %s", id, name, email)}Importante: Siempre maneje sql.NullInt64 para campos nullable, para evitar pánico con valores NULL.