Un pool de conexiones es un conjunto limitado de conexiones a una base de datos, que es manejado por un servidor de aplicaciones de forma tal, que dichas conexiones pueden ser reutilizadas por los diferentes usuarios.
Introducción
Persistencia de datos en Node.js
Platzi Store: instalación y presentación del proyecto
Base de datos
Instalación de Docker
Configuración de Postgres en Docker
Explorando Postgres: interfaces gráficas vs. terminal
Integración de node-postgres
Manejando un Pool de conexiones
Variables de ambiente en Node.js
Sequelize
¿Qué es un ORM? Instalación y configuración de Sequelize ORM
Tu primer modelo en Sequelize
Crear, actualizar y eliminar
Cambiando la base de datos a MySQL
Migraciones
¿Qué son las migraciones? Migraciones en Sequelize ORM
Configurando y corriendo migraciones con npm scripts
Modificando una entidad
Relaciones
Relaciones uno a uno
Resolviendo las relaciones uno a uno
Relaciones uno a muchos
Resolviendo relaciones uno a muchos
Consultas
Órdenes de compra
Relaciones muchos a muchos
Resolviendo relaciones muchos a muchos
Paginación
Filtrando precios con operadores
Despliegue
Deploy en Heroku
Consideraciones al hacer migraciones
Próximos pasos
Toma con el Curso de Backend con Node.js: Autenticación con Passport.js y JWT
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 19
Preguntas 16
Un pool de conexiones es un conjunto limitado de conexiones a una base de datos, que es manejado por un servidor de aplicaciones de forma tal, que dichas conexiones pueden ser reutilizadas por los diferentes usuarios.
Manejando un Pool de conexiones
Hay un problema con getConnection. El problema es que cada vez que llamamos a getConnection, lo que hacemos internamente en el codigo es llamar y llamar y llamar, es decir hacer request continuamentes, eso esta mal porque puede sobrecargar el servidor de request. Entonces, esto es un problema porque por cada request se crea una negociacion con la db, se tarda 20ms o mas, y asi vamos saturando el servidor. La solucion es usar pool.
Sin un pool, yo deberia cerrar las conexiones manuelament.e
Que es un pool? Un pool de conexiones es un conjunto limitado de conexiones a una base de datos, que es manejado por un servidor de aplicaciones de forma tal, que dichas conexiones pueden ser reutilizadas por los diferentes usuarios. Un pool optimiza
Lo que hace el pool es sencillamente es ser un mediador entre las bases de datos y el cliente. Entonces a medida que los clientes empiecen a hacer consultas, la aplicacion de manera asincrona conectara con el pool y el pool se encargara tanto de abrir o cerrar conexiones para que la informacion siga trabajando de manera eficiente. Pero un pool es mucho mas inteligente que eso, ya que permite REUTILIZAR DATA QUE OTROS CLIENTES YA ACCEDIERON, CLARO SIEMPRE Y CUANDO LA DATA A REUTILIZAR SEA LA MISMA QUE ESOS CLIENTES NECESITABAN , y a su vez lograremos que los servidores no se saturen y nuestra app en el background trabajara con las consultas, y asi evitara un problema en el proceso.
Comparto mi código para el create, delete y update para las categorías.
Documentación https://node-postgres.com/features/pooling
users.service.js
const boom = require('@hapi/boom');
const pool = require('../libs/postgres.pool');
const getConnection = require('../libs/postgres');
class UserService {
constructor() {
this.users = [];
this.pool = pool;
this.pool.on('error', (err) => console.error(err));
}
async create(data) {
return data;
}
async find() {
const query = 'SELECT * FROM tasks';
const rta = await this.pool.query(query);
return rta.rows;
}
async findOne(id) {
return { id };
}
async update(id, changes) {
return {
id,
changes,
};
}
async delete(id) {
return { id };
}
}
module.exports = UserService;
Ese pool es básicamente un singleton
la verdad en este curso en específico estoy teniendo muchos problemas con el código, estoy recibiendo errores como this.pool.query(query);
Mi resumen!
Ahora,mostrare como el codigo ha cambiado:
//libs/postgres.pool.js
const { Pool } = require('pg');
const pool = new Pool({
host: 'localhost',
port: 5432,
user: 'nico',
password: 'admin123',
database: 'my_store'
});
//Fijate que el codigo ha cambiado, ahora el trabajar con el driver pg no se basa en ser una funcion, sino mas bien un objeto. y desde aca empezamos a trabajar con pool, fijate las variables... Ahora tambien se puede aprecier que el codigo es mas simple.
module.exports = pool;
// services/product.service.js
//En este archivo elimine unas lineas de codigo para que sea mas facil de entender y asi no ver todo el codigo que no importa
class ProductsService {
constructor(){
this.products = [];
this.generate();
**this.pool = pool
this.pool.on('error', (err) => console.error(err)) //1)**
}
async find() {
const query = 'SELECT * FROM tasks'
const rta = await this.pool.query(query);
return rta.rows; //2) Accedemos a pool y especifcamente le passamos el query que este metodo necesita
}
Por lo tanto, lo que podemos entender es que: la class ProductService crea un canal con el servidor con el mediador pool. Y cada servicio dentro de la clase genera su consulta adecuada. Por lo tanto, Otro archivo como no se… category.service, accedera a pool y abrira otro canal y accedera con su servicios por otro canal.
Yo no agregue un nuevo script para manejar el pool de conexiones, por el contrario lo agregué al que ya tenia
Una vez realizado esto, modifique todo mi servicio para que usara el connection pool con promesas:
Tuve que hacer ciertas modificaciones porque ahora mis campos de producto cambiaron:
Pero una vez realizados estos ajustes pude usar todos mis endpoints hacia la base de datos de forma fluida
Hasta este punto por cada llamado a de un servicio a la base de datos se esta creando una conexión, de implementarse asi en todos los servicios se estarian creado multiples conexiones y esto no seria una buena practica.
Aquí entra la interfaz de Pool de conexiones que permite usar varias conexiones en toda la aplicación pero reutilizando la primera.
Del modulo de pg admin importaremos el modulo de Pool y utilizaremos la siguiente configuración en un nuevo archivo dentro de libs llamado postgres.pool.js:
Ahora se debe implementar en los servicios, donde se remplazara la conexión que anteriormente se tenia de la siguiente manera.
Use un patron singleton para asegurarme de solo usar una instancia de la conexion al pool
import { Pool as PostgresClient } from 'pg';
export default class PostgressPool {
private static connection: PostgresClient | null = null;
private constructor() {}
public static getInstance(): PostgresClient {
if (!PostgressPool.connection) {
PostgressPool.connection = new PostgresClient({
host: 'localhost',
port: 5432,
user: 'root',
password: 'root',
database: 'my_store'
});
console.log('Connected successfully');
}
return PostgressPool.connection;
}
public async query(request: string) {
try {
const db = PostgressPool.getInstance();
return await db.query(request);
} catch (error) {
console.log(error);
}
}
}
Corrijanme si me equivoco, pero creo que una manera eficiente de colocar el pool
y el pool.on("error")
es crear una clase base e extenderla en los demas servicios:
export abstract class Services implements IServices {
pool: Pool;
constructor() {
this.pool = pool;
}
}
Y podrias extenderlas de la siguiente manera (utilizando typescript):
class ArticlesServices extends Services {
constructor(
public perro = "perrito",
) {
super();
}
async create() {
}
async find() {
}
async findOne(slug: string) {
}
async update() {
}
async delete() {
}
}
``
Muy agradecido con Platzi, he aprendido bastante con los cursos. Muchas gracias!
Manejando un Pool de conexiones
Modificamos el archivo creado en libs, y modificamos Client por Pool
const { Pool } = require('pg');
const pool = new Pool({
host: "localhost",
port:5432,
user:"juancacode",
password:"admin123",
database:'my_store_db'
})
module.exports = pool;
Llamamos en nuestro servicio
const pool = require(’…/libs/postgres.pool’);
modificamos el constructor
class ProductsService {
constructor() {
this.products = [];
this.generate();
this.pool = pool;
this.pool.on('error',(err)=>console.error(err));
}
lo aplicamos a la función
async find() {
const query = "SELECT * FROM tasks";
const res = await this.pool.query(query);
return res.rows;
}
Me gustaria que se brinde una solucion a como conectar los servicios a la Base de Datos. Me parece muy mal que se indique al alumno “realicen todas las demas conexiones a los servicios” teniendo una minima guia con la tabla tasks.
Creo que pooling esta relacionado con los websockets, creo que son Event emitters incluso lo de > this.pool.on(‘error’, cb)
es algo que se usa en webSockets si saben Socketio sabrán a lo que me refiero.
Mi update:
async update(id, changes) {
try {
const keys = Object.keys(changes);
const values = Object.entries(changes).map((b) => b[1]);
const updates = keys.map((key, index) => ${key}=$${index + 1}
).join();
const query = UPDATE users SET ${updates} WHERE id = $${ keys.length + 1 }
;
await this.pool.query(query, […values, id]);
return {
id,
…changes,
};
} catch (error) {
return ‘Error on updating’ + error;
}
}
Super, ya quedo el pool en cada service
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?