Introducción

1

Conexiones a Bases de Datos con Time OEM y NetsGIS

2

Integración de Datos con Next.js y Time ORM en Proyectos E-commerce

Database

3

Instalación de Docker en Windows, macOS y Ubuntu

4

Configuración de Postgres en Docker Compose

5

Conexión a Postgres en Docker: Terminal y PgAdmin

6

Conexión de NestJS a Postgres con Node Postgres

7

Inyección de Dependencias en NETJS: Conexión a PostgreSQL

8

Conexión a Bases de Datos con Variables de Entorno en Node.js

TypeORM

9

Implementación de TypeORM con NestJS en Proyectos Node.js

10

Creación de Entidades en ORM para Tiendas Virtuales

11

Implementación del Patrón Repository en NestJS con TypeORM

12

Operaciones CRUD en ProductService usando TypeORM y Postgres

13

Cambio de Postgres a MySQL en Docker para CRUD de Productos

Migraciones

14

Configuración de Migraciones en Bases de Datos con TimeORM

15

Configuración y uso de migraciones con TimeORM y TypeScript

16

Ejecución y gestión de migraciones con Time1M en Node.js

17

Migraciones en bases de datos: agregar campos automáticamente

Relaciones

18

Relaciones 1 a 1 en Bases de Datos con TimeORM

19

Manipulación de Relaciones Uno a Uno en Controladores y Servicios

20

Relaciones Uno a Muchos en Bases de Datos con TypeORM

21

Gestión de Relaciones Uno a Muchos en Controladores de API

22

Relaciones Muchos a Muchos en Time1M: Creación y Manejo Práctico

23

Manipulación de Relaciones Muchos a Muchos en Controladores

24

Manipulación de Relaciones Muchos a Muchos con TimeORM en JavaScript

25

Relaciones Muchos a Muchos con Campos Agregados en TimeWareM

26

CRUD de órdenes de compra y gestión de ítems en NestJS

Consultas

27

Paginación de Productos con Limit y Offset en Controladores API

28

Filtrado de Precios con Rango Usando Between en Time Wareham

29

Indexación de Parámetros en Bases de Datos: Uso y Precauciones

30

Buenas prácticas de nombramiento en JavaScript y bases de datos

31

Serialización y Transformación de Datos en APIs con ClassTransformer

Migración a NestJS 9 y TypeORM 0.3

32

Actualización de dependencias en NEST y TimeWareM

33

Migración y ajustes en TimewareM 0.3: Cambios en métodos y servicios

34

Actualización de Migraciones en TimeWareM 0.3

Próximos pasos

35

Soluciones a referencias circulares en módulos NestJS

36

Persistencia de Datos con Time Ware M: Conexiones y Buenas Prácticas

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Cambio de Postgres a MySQL en Docker para CRUD de Productos

13/36
Recursos

¿Cómo cambiar de Postgres a MySQL utilizando Docker?

Cambiar de un motor de base de datos a otro puede parecer una tarea difícil, pero con Docker y las herramientas adecuadas, es un proceso bastante sencillo. Si estás trabajando con Time Warp M y deseas cambiar de Postgres a MySQL, solo necesitas algunos pasos clave que te detallo a continuación, asegurándote de que tu proyecto se ejecute sin problemas en MySQL.

¿Cómo configurar el servicio de MySQL?

Para empezar con MySQL, no es necesario instalarlo directamente en tu máquina. Puedes llevar a cabo todo este proceso con Docker, que te ayudará a correr MySQL en un contenedor aislado. Aquí tienes cómo configurarlo:

  1. Configurar el contenedor de MySQL:
    • Debes declarar en tu archivo docker-compose que vas a tener un servicio de MySQL.
    • Especifica la versión que desees usar. Un estándar común es la versión 5 de MySQL.
    • Establece las variables de entorno necesarias, como:
      • MYSQL_DATABASE: nombre de la base de datos.
      • MYSQL_USER: nombre de usuario (por ejemplo, "root").
      • MYSQL_ROOT_PASSWORD: clave de acceso para root.
    • Conecta el puerto de MySQL (3306) para que sea accesible desde tu máquina local.
    • Define un volumen para asegurarte de que la persistencia de datos esté habilitada.
    • Añade MYSQL_data a tu archivo .gitignore para evitar subir los archivos de persistencia al repositorio.
services:
  mysql:
    image: mysql:5
    environment:
      - MYSQL_DATABASE=my_database
      - MYSQL_USER=root
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

¿Cómo visualizar la base de datos MySQL?

Una vez que tienes MySQL configurado, seguramente querrás monitorear y manejar tus bases de datos sin complicaciones. Aquí es donde entra phpMyAdmin:

  1. Configurar phpMyAdmin:
    • Añade un nuevo servicio en docker-compose para phpMyAdmin.
    • Define las variables de entorno necesarias para que phpMyAdmin pueda conectarse a MySQL.
    • Asegúrate de que se comunique internamente a través del puerto correcto (8080 en la máquina local, 80 en el contenedor).
services:
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_HOST=mysql
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - "8080:80"
    depends_on:
      - mysql

¿Cómo solucionar problemas comunes al configurar MySQL?

Como en todos los sistemas, podría encontrarse con algunos problemas comunes durante la configuración:

  • Error de puerto ya en uso: Si Docker indica que el puerto 3306 ya está en uso, por otro servicio o contenedor, identifica y detén el contenedor que está utilizando ese puerto utilizando:
docker stop <container_id>
  • Problemas de conexión con phpMyAdmin: Asegúrate de que las variables de entorno están configuradas correctamente, recuerda que PMA_HOST debe estar en mayúsculas y correctamente señalado a mysql.

¿Cómo actualizar la configuración para MySQL en tu aplicación?

Con la infraestructura de MySQL lista, tendrás que actualizar algunos aspectos de tu aplicación para que funcione correctamente con MySQL:

  1. Actualizar las variables de entorno: Asegúrate de que las variables en tu código fuente reflejen las configuraciones para MySQL.

  2. Modificar el módulo de la base de datos en la aplicación:

    • Cambia la conexión del módulo de base de datos de Postgres a MySQL.
    • Verifica que todas las configuraciones (como las rutas de acceso, credenciales y puertos) están establecidas correctamente.
import { TypeOrmModule } from '@nestjs/typeorm';

TypeOrmModule.forRoot({
  type: 'mysql',
  host: process.env.MYSQL_HOST,
  port: +process.env.MYSQL_PORT,
  username: process.env.MYSQL_USER,
  password: process.env.MYSQL_ROOT_PASSWORD,
  database: process.env.MYSQL_DATABASE,
  entities: [/* tus entidades */],
  synchronize: true,
});
  1. Instalar el driver necesario: Al cambiar a MySQL, necesitas instalar el driver correspondiente para Node.js, normalmente mysql2.
npm install mysql2

Probar la conexión y asegurarse de que todo funciona

Finalmente, después de realizar todos los cambios, ejecuta nuevamente tu aplicación para asegurarte de que todo funcione correctamente. Revisa tus tablas y productos en phpMyAdmin para confirmar que los datos se están almacenando finalmente en MySQL. Esto puede ser verificado realizando solicitudes CRUD desde tu aplicación y comprobando el estado de tus datos en phpMyAdmin.

Recuerda, el cambio de Postgres a MySQL no solo es una prueba de concepto, sino también una experiencia de aprendizaje que puede reforzar tus habilidades en administración de bases de datos, Docker, y desarrollo web en general. ¡Atrévete a explorar e implementar en tus proyectos!

Aportes 16

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Si tienen algún problema con la autenticación de root, pueden probar eliminando MYSQL_USER=root del environment.
La conexión quedaría así:

  mysql:
    image: mysql:5
    environment:
      - MYSQL_DATABASE=platzi_store
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - '3306:3306'
    volumes:
      - ./mysql_data:/var/lib/mysql

Les dejo como configure los 2 motores en simultaneo:

Config:

import { registerAs } from '@nestjs/config';

export default registerAs('config', () => {
  return {
    postgres: {
      dbName: process.env.POSTGRES_DB,
      port: parseInt(process.env.POSTGRES_PORT, 10),
      user: process.env.POSTGRES_USER,
      password: process.env.POSTGRES_PASSWORD,
      host: process.env.POSTGRES_HOST,
    },
    mysql: {
      dbName: process.env.MYSQL_DB,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
      port: parseInt(process.env.MYSQL_PORT),
      host: process.env.MYSQL_HOST,
    },
    apiKey: process.env.API_KEY,
    configuration: process.env.CONFIGURATION,
  };
});

Schema:

import * as Joi from 'joi';

export const pgSchema = Joi.object({
  API_KEY: Joi.number().required(),
  POSTGRES_DB: Joi.string().required(),
  POSTGRES_USER: Joi.string().required(),
  POSTGRES_PASSWORD: Joi.string().required(),
  POSTGRES_HOST: Joi.string().required(),
  POSTGRES_PORT: Joi.number().required(),
  PORT: Joi.number().required(),
});

export const mysqlSchema = Joi.object({
  MYSQL_DB: Joi.string().required(),
  MYSQL_USER: Joi.string().required(),
  MYSQL_PASSWORD: Joi.string().required(),
  MYSQL_HOST: Joi.string().required(),
  MYSQL_PORT: Joi.number().required(),
});

Database Module:

imports: [
    TypeOrmModule.forRootAsync({
      name: 'mysqlDB',
      useFactory: (configService: ConfigType<typeof config>) => {
        const { dbName, user, password, host, port } = configService.mysql;
        return {
          type: 'mysql',
          host,
          port,
          username: user,
          password,
          database: dbName,
          synchronize: true,
          autoLoadEntities: true,
        };
      },
      inject: [config.KEY],
    }),
    TypeOrmModule.forRootAsync({
      name: 'postgresDB',
      useFactory: (configService: ConfigType<typeof config>) => {
        const { dbName, user, password, host, port } = configService.postgres;
        return {
          type: 'postgres',
          host,
          port,
          username: user,
          password,
          database: dbName,
          synchronize: true,
          autoLoadEntities: true,
        };
      },
      inject: [config.KEY],
    }),
  ],

Products Module:

@Module({
  imports: [TypeOrmModule.forFeature([Product, Category, Brand], 'mysqlDB')],
  controllers: [ProductsController, CategoriesController, BrandsController],
  providers: [ProductsService, CategoriesService, BrandsService],
  exports: [ProductsService],
})

Product Service:

constructor(
    @InjectRepository(Product, 'mysqlDB')
    private productRepo: Repository<Product>,
  ) {}

Si tienes el puerto ocupado (y no por un contenedor):
$ sudo lsof -i -n -P|grep 3306

luego:
$ sudo kill nro_del_PDI

y lanza de nuevo :
$ docker-compose up -d phpmyadmin

Conexion con SQL Server

En las variables de entorno, habria que agregar:

SQLSERVER_DATABASE=my_db
SQLSERVER_USER=sa
SQLSERVER_SA_PASSWORD=1SuperPassword1
SQLSERVER_PORT=1433
SQLSERVER_HOST=localhost

Use la imagen del 2017, porque por alguna razon no me toma los volumes la 2019.

Agregar el servicio al docker-compose.yml

  sql-server:
    image: mcr.microsoft.com/mssql/server:2017-latest
    ports:
      - "1433:1433"
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=SuperPassword(!)
      - MSSQL_PID=Express
    volumes:
      - ./sqlserver:/var/opt/mssql

Imagen: https://hub.docker.com/_/microsoft-mssql-server
Por alguna razon microsoft no agrego la variable de entorno para crear la base de datos por defecto. Por lo que entren con el IDE al motor y crean la base de datos my_db

Pueden ver todo el hilo aqui con el issue cerrado: https://github.com/Microsoft/mssql-docker/issues/2

Ejecutar docker-compose up -d sql-server para levantar el servidor.

Instalar el driver npm install --save mssql
Fuente: https://www.npmjs.com/package/mssql

En config.ts agregar la coleccion del sql-server:

...
    sqlserver: {
      dbName: process.env.SQLSERVER_DATABASE,
      port: parseInt(process.env.SQLSERVER_PORT),
      password: process.env.SQLSERVER_SA_PASSWORD,
      user: process.env.SQLSERVER_USER,
      host: process.env.SQLSERVER_HOST,
    },
...

En el database.module.ts se agrega el objeto de conexion

      useFactory: (configService: ConfigType<typeof config>) => {
        const { user, host, dbName, password, port } = configService.sqlserver;
        return {
          type: 'mssql',
          host,
          port,
          username: user,
          password,
          database: dbName,
          synchronize: true,
          autoLoadEntities: true,
          options: {
            encrypt: false,
          },
        };
      },

Para quienes esten siguiendo el curso en este momento
La configuracion para mysql es la siguiente

  mysql:
    image: mysql:8
    environment:
     - MYSQL_DATABASE=my_db
     - MYSQL_ROOT_PASSWORD=123456
    ports:
      - '3306:3306'
    volumes:
      - ./mysql_data:/var/lib/mysql

Lo que vimos:

.env

MYSQL_DATABASE=my_db
MYSQL_USER=root
MYSQL_ROOT_PASSWORD=123456
MYSQL_PORT=3306
MYSQL_HOST=localhost

config.ts

mysql: {
      host: process.env.MYSQL_HOST,
      dbName: process.env.MYSQL_DATABASE,
      port: parseInt(process.env.MYSQL_PORT, 10),
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_ROOT_PASSWORD,
    },

database.module.ts

imports: [
    TypeOrmModule.forRootAsync({
      inject: [config.KEY],
      useFactory: (configService: ConfigType<typeof config>) => {
        const { user, password, host, dbName, port } = configService.mysql;

        return {
          type: 'mysql',
          host,
          port,
          username: user,
          password,
          database: dbName,
          synchronize: true,
          autoLoadEntities: true,
        };
      },
    }),
  ],

Con mariadb:

Si estan en una mac con m1 no olviden de especificar antes de la imagen de mysql la plataforma

mysql:
    platform: linux/x86_64
    image: mysql:5

en mi caso para poder ver el phpmyadmin tuve que colocar el password: root porque el 123456 no funciono

Recuerden que synchronize es solo para DEV

import { Module, Global } from '@nestjs/common';
import { Client } from 'pg';
import { ConfigType } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import config from '../config/config';

const API_KEY = 'ASdasdasd';
const API_KEY_PROD = 'PRODasdasdas';

@Global()
@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      inject: [config.KEY],
      useFactory: (configService: ConfigType<typeof config>) => {
        const { user, host, dbName, password, port } = configService.mysql;

        return {
          type: 'mysql',
          host: host,
          port: port,
          username: user,
          password: password,
          database: dbName,
          synchronize: process.env.NODE_ENV === 'prod' ? false : true,
          autoLoadEntities: process.env.NODE_ENV === 'prod' ? false : true,
        };
      },
    }),
  ],
  providers: [
    {
      provide: 'API_KEY',
      useValue: process.env.NODE_ENV === 'prod' ? API_KEY_PROD : API_KEY,
    },
    {
      provide: 'PG',
      useFactory: (configService: ConfigType<typeof config>) => {
        const { user, host, dbName, password, port } = configService.postgres;
        const client = new Client({
          user,
          host,
          database: dbName,
          password,
          port,
        });
        client.connect();
        return client;
      },
      inject: [config.KEY],
    },
  ],
  exports: ['API_KEY', 'PG', TypeOrmModule],
})
export class DatabaseModule {}

Si tienen Windows y les devuelve el error:

ERROR: for mysql  Cannot start service mysql: Ports are not available: listen tcp 0.0.0.0:3306

Iniciar el Administrador de tareas, ir a la pestaña de Servicios y detener el servicio de MySQL80. Luego volver a correr el contenedor:

docker-compose up -d mysql
docker-compose up -d phpmyadmin

Por si alguien está haciendo el curso con un Mac con chip M1 para la fecha en la que pongo este comentario todavía no está adaptado el contenedor de MySql si intentáis correrlo como el profesor os dará un error para evitar este error solo tenéis que ponerlo como este:

mysql:
    image: mysql:5
    platform: linux/x86_64
    environment:
      - MYSQL_DATABASE=my_db
      - MYSQL_USER=root
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - '3306:3306'
    volumes:
      - ./data/mysql_data:/var/lib/mysql

Si alguien tiene un problema como el siguiente:

ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries

Se puede solucionar agregrando lo siguiente en mysql:

platform: linux/amd64

😍 TypeORM

👏

En mi caso si funciono la parte con mysql
cuando usaba postgres me salia error con el password no se por que pero al menos mysql funciona

Que excelente explicación de Nico