Introducci贸n

1

驴Ya terminaste el Curso de NestJS: Programaci贸n Modular?

2

Platzi Store: presentaci贸n del proyecto e instalaci贸n

Database

3

C贸mo instalar Docker para este proyecto

4

Configuraci贸n de PostgresSQL en Docker

5

Explorando postgres con interfaces gr谩ficas y terminal

6

Integraci贸n de node-postgres con NestJS

7

Conexi贸n como inyectable y ejecutando un SELECT

8

Usando variables de ambiente

TypeORM

9

驴Qu茅 es un ORM? Instalando y configurando TypeORM Module

10

Creando tu primera entidad

11

TypeORM: active record vs. repositories

12

Crear, actualizar y eliminar

13

Cambiar a Mysql demo (opcional)

Migraciones

14

Sync Mode vs. Migraciones en TypeORM

15

Configurando migraciones y npm scripts

16

Corriendo migraciones

17

Modificando una entidad

Relaciones

18

Relaciones uno a uno

19

Resolviendo la relaci贸n uno a uno en el controlador

20

Relaciones uno a muchos

21

Resolviendo la relaci贸n uno a muchos en el controlador

22

Relaciones muchos a muchos

23

Resolviendo la relaci贸n muchos a muchos en el controlador

24

Manipulaci贸n de arreglos en relaciones muchos a muchos

25

Relaciones muchos a muchos personalizadas

26

Resolviendo la relaci贸n muchos a muchos personalizada en el controlador

Consultas

27

Paginaci贸n

28

Filtrando precios con operadores

29

Agregando indexadores

30

Modificando el naming

31

Serializar

Migraci贸n a NestJS 9 y TypeORM 0.3

32

Actualizando Dependencias para NestJS 9

33

Cambios en TypeORM 0.3

34

Migraciones en TypeORM 0.3

Pr贸ximos pasos

35

C贸mo solucionar una referencia circular entre m贸dulos

36

Contin煤a con el Curso de NestJS: Autenticaci贸n con Passport y JWT

No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Cambiar a Mysql demo (opcional)

13/36
Recursos

Aportes 15

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

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

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,
          },
        };
      },

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>,
  ) {}

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

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