ORM en Node.js: Introducción a Sequelize y Mongoose para Bases de Datos SQL y NoSQL

En este post aprenderemos cómo establecer la conexión a nuestra base de datos desde un proyecto en Node.js utilizando ORM (Object-Relational Mapping). Los ORM facilitan no solo la conexión con la base de datos, sino que también simplifican la interacción con la misma, permitiendo realizar consultas de manera más estructurada y eficiente.

Nos enfocaremos en dos ORM populares: Sequelize y Mongoose. Estas librerías permiten trabajar con bases de datos SQL y NoSQL, respectivamente.

  • Sequelize es un ORM robusto y flexible que soporta varios motores de bases de datos relacionales como PostgreSQL, MySQL, SQLite, y SQL Server. Con Sequelize, puedes gestionar de forma sencilla la estructura de tus tablas, definir relaciones entre ellas, y realizar consultas usando un estilo declarativo en lugar de escribir SQL directamente.

  • Mongoose, por otro lado, está diseñado específicamente para bases de datos NoSQL como MongoDB. Con Mongoose, podrás crear esquemas que definan la estructura de tus documentos y realizar operaciones de lectura y escritura de una forma intuitiva, además de contar con herramientas útiles como validación y middlewares para facilitar la gestión de tus datos.

A lo largo de este post, veremos cómo configurar estas librerías, establecer la conexión a sus respectivas bases de datos, y realizar operaciones CRUD de manera eficiente, mejorando la productividad en el desarrollo de aplicaciones Node.js.

Dado que ya hemos comprendido el propósito de cada uno de los ORM que utilizaremos a lo largo de este artículo, es momento de profundizar en la configuración dentro de nuestro proyecto. A continuación, veremos cómo establecer la conexión con nuestra base de datos de manera efectiva.

Comencemos configurando la conexión con la librería Mongoose para una base de datos no relacional como MongoDB. Para ello, es necesario que previamente hayas creado la base de datos, ya sea de forma local o en la nube.

Para ello lo primero que debemos de hacer es dentro de nuestro proyecto crearemos una carpeta llamada config en la cual llevara todos los archivos de nuestras configuraciones en este caso solo crearemos dos archivos, uno para la configuración de la conexión de mongodb y el otro para la configuración de la base de datos de postgresql.

El primer archivo que crearemos sera la configuracion de mongoD

const mongoose = require('mongoose');

const mongoURI = process.env.MONGO_URI 

const connectMongoDB = async () => {
  try {
    await mongoose.connect(mongoURI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    console.log('MongoDB connected successfully');
  } catch (error) {
    console.error('Error connecting to MongoDB:', error);
    process.exit(1);
  }
}

En el código, podemos observar cómo se establece la conexión a nuestra base de datos NoSQL utilizando la librería Mongoose. Primero, importamos Mongoose y luego definimos una variable que contiene la URL de conexión a MongoDB. Por motivos de seguridad, la URL se almacena como una variable de entorno. Un ejemplo de la URL sería algo como 'mongodb://127.0.0.1:27017/test', donde después de los dos // se especifica la dirección de la base de datos, seguida del puerto y el nombre de la base de datos.

Una vez tengamos la librería importada y la url de la conexión a la base de datos creamos una función asincrónica para la conexión a la base de datos, como podemos ver usamos una función propia de la librería mongoose que se llama connect, esta función recibe como primer parámetro le url de la conexión a la base de datos, como segundo parámetro se le puede pasar un objeto de opciones, dependiendo de las necesidades de tu proyecto se puede configurar ciertas opciones para la configuración de la conexión a la base de datos.

Algunas de las opciones son:

  • dbName: Esta opción indicara que base de datos se usara en el proyecto anulando cualquier base de datos indicada en la cadena de conexión.

  • autoIndex: Esta opción configurada como false lo que hará es evitar crear indices automáticos en los modelos cuando se insertan los registros.

  • useNewUrlParser: Esta opción nos evitara ver en la consola una advertencia ya que el controlador de Node.js de MongoDB reescribió la herramienta que utiliza para analizar las cadenas de conexión de MongoDB . Debido a que este es un cambio tan grande, colocaron el nuevo analizador de cadenas de conexión detrás de una bandera. Por tal motivo se genera la advertencia por consola.

  • useUnifiedTopology: Esta opción al igual que la anterior evita que se imprima una alerta en la consola esto es debido a que Mongoose 5.7 utiliza el controlador MongoDB 3.3.x, que introdujo una importante reestructuración de la forma en que gestiona la supervisión de todos los servidores en un conjunto de réplicas o un clúster fragmentado. En el lenguaje de MongoDB, esto se conoce como detección y supervisión de servidores . La useUnifiedTopologyopción elimina la compatibilidad con varias opciones de conexión que ya no son relevantes con el nuevo motor de topología: autoReconnect, reconnectTries, reconnectInterval. Cuando habilite useUnifiedTopology, elimine esas opciones de sus mongoose.connect()o createConnection()

En nuestra conexión estamos usando solo las opciones useNewUrlParser y useUnifiedTopology para evitar alertas en nuestra consola.

Ya teniendo nuestra configuración en la conexión a la base de datos de mongodb podremos estanciarla en cualquier lugar de nuestro aplicativo para conectarnos a la base de datos.

Ahora realizaremos nuestra configuración de la base de datos relacional usando el orm sequealize que nos ayudara a realizar una conexión y manejo de la base de datos de manera mas fácil.

Lo que tenemos que hacer como primer paso es instalar nuestra librería sequealize ejecutando en nuestro proyecto el siguiente comando:

npm install --save sequelize

Luego procedemos a instalar el controlador para la base de datos que utilizaremos en este caso utilizaremos el motor postgreql por lo tanto el comando que ejecutaremos es el siguiente:

npm install --save pg pg-hstore

Luego de ejecutar ambos comandos procederemos a crear el archivo postgresql en la carpeta config en el cual configuraremos la conexión a la base de datos, en este archivo ingresaremos el siguiente código:

require('dotenv').config()

const { Sequelize } = require('sequelize')

const db = new Sequelize(
  process.env.DB_NAME || '',
  process.env.DB_USER,
  process.env.DB_PASSWORD,
  {
    host: process.env.HOST,
    dialect: 'postgres',
    protocol: 'postgres',
    logging: process.env.NODE_ENV === 'development' ? console.log : false,
    /* define:{
            freezeTableName: true,
            timestamps: false
        }, */
   pool: {
      max: 10,
      min: 2,
      acquire: 60000,
      idle: 20000
    },
    // Habilitar si la BD esta en la nube
    /*dialectOptions: {
      ssl: true,
      native: true
       {
                require: true, // This will help you. But you will see nwe error
                rejectUnauthorized: false // This line will fix new error
       }
    }*/
  }
)

module. Exports = db

Lo primero que hicimos fue importar las variables de entorno y la librería en la primera línea para poder usarlas en nuestro archivo de configuración, luego creamos la constante que instancia la librería de sequealize y que llevara toda la configuración de la librería, esa configuración es la siguiente.

Lo primero que le indicamos a la configuración es el host donde esta nuestra base de datos, lo segundo y tercero es el dialecto y el protocolo que en este caso se postgres, luego le indicaremos si queremos que se muestren cada sentencia que haga la librería en consola esto nos ayudara a debuguear nuestra aplicación en tiempo real y localizar nuestros errores de sql en la aplicación de una manera mas eficiente y rápida, en nuestro caso validamos a través de una variable de entorno si estamos en producción o en desarrollo así debuguearemos solo cuando estemos desarrollando.

Luego viene una configuración que afecta nuestros modelos, el primero es freezeTableName esta propiedad le indicara a sequealize que todas las tablas tendrán el mismo nombre que nuestro modelo, la segunda propiedad es timestamps esta propiedad configura que sequealice maneje los campos de updated_at y created_at los cuales ingresan la fecha de creación del registro en la tabla y la fecha de la actualización.

Luego viene la configuración del pool de conexión:

  • Max: indicamos el máximo de conexiones.

  • Min: mínimo de conexiones.

  • Idle: El tiempo máximo, en milisegundos, que una conexión puede estar inactiva antes de liberarse.

  • Acquire: El tiempo máximo, en milisegundos, que ese grupo intentará obtener la conexión antes de generar un error

Luego viene la configuración que se usaría en caso tal que nuestra base de datos relacional esta en la nube como por ejemplo en AWS o cualquier servicio de host que se encuentre en la nube.

Luego de tener nuestra configuración de sequealize podremos llamarla en cualquier lugar de nuestro aplicativo para establecer la conexión y manipular la base de datos.

En nuestro caso haremos el llamado de la conexión en nuestro modelo server para establecer la conexión al inicio de nuestra aplicación y cuando se ejecute la aplicación se conecte, lo que haremos es lo siguiente:

async dbConecction () {
    try {
      await db.authenticate()
      console.log('Database Online')
    } catch (error) {
      console.error('Error al conectar con la base de datos sql:', error);
      process.exit(1); // Finalizar proceso si la base de datos no está disponible
    }

    try {
      await connectMongoDB();  
    } catch (error) {
      console.error('Error al conectar con la base de datos no sql:', error);
      process.exit(1); // Finalizar proceso si la base de datos no está disponible
    }

  }

En esta función estamos llamando la configuración de ambas bases de datos y controlamos los errores para detectar si no se estableció la conexión en alguna de ellas y ver el error en consola.

Luego esta función llamaremos en nuestro constructor del modelo server y de esta manera tendremos la conexión a ambas bases de datos y podremos usar la librería en cualquier lugar de nuestra aplicación y manipular la base de datos.

En pasados post vimos como hacer el modelo y hacer consultas con sequealize.

0
Subscribe to my newsletter

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

Written by

Alejandro Benjumea Aguirre
Alejandro Benjumea Aguirre

¡Hola! Soy Alejandro Benjumea Aguirre, un apasionado desarrollador de software con experiencia en el desarrollo de aplicaciones web y tecnologías backend. Actualmente, trabajo como desarrollador junior en una empresa que desarrolla soluciones tecnológicas para el sector salud. Tengo una sólida formación en análisis y desarrollo de sistemas de información, habiendo egresado del SENA, y actualmente estoy cursando Ingeniería en Sistemas en la UNAD. Mi objetivo es seguir creciendo como desarrollador backend, contribuir a proyectos de código abierto y mejorar mis habilidades en el uso de tecnologías modernas.