¿Cómo integrar TimeORM para gestionar migraciones?
Integrar un sistema de migraciones en tu proyecto es crucial para la gestión eficiente y ordenada de los cambios en tu base de datos. TimeORM, con su CLI, te facilita este proceso de manera automatizada, similar a cómo lo hace NEST para APIs. Aprenderás a configurar y correr migraciones utilizando TimeORM, optimizando así la adaptación de tu base de datos a cambios en tu aplicación. ¡Vamos al código!
¿Cómo configuramos las migraciones?
Para configurar migraciones con TimeORM, es fundamental entender que requiere una conexión y configuración propias, diferentes a las de tu aplicación NEST. Puedes optar por usar un archivo ormconfig.json o, preferiblemente, integrar variables de ambiente que añadan flexibilidad.
Crea el archivo de configuración: Define conexiones, host, usuario, password, tipo de base de datos y puerto. Un ejemplo para una base de datos PostgreSQL:
Entidades y migraciones en TypeScript: Cambia a TypeScript ajustando los paths para buscar archivos .ts. Utiliza expresiones regulares como dist/**/*.entity{.ts,.js} para que reconozca las entidades.
¿Cómo ajustar el package.json para TimeORM?
Modifica el package.json para incluir scripts que manejen el CLI de TimeORM, facilitando la ejecución de comandos desde tu proyecto.
Actualiza los scripts:
Añade un script para ejecutar el CLI de TimeORM utilizando ts-node.
"scripts":{"typeorm":"ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js","migration:generate":"npm run typeorm migration:generate -- -n"}
Ejecuta migraciones:
En consola, usa el script para generar una nueva migración nombrada:
npm run migration:generate -- -n InitialMigration
¿Qué problemas comunes podemos encontrar y cómo solucionarlos?
Al integrar sistemas complejos como TimeORM, es común enfrentar errores. Aquí te comparto algunos y cómo resolverlos:
Errores de conexión: Verifica que las variables de entorno estén correctamente configuradas sin typos y que el servicio de tu base de datos esté activo.
Problemas con TypeScript: Asegúrate de que el CLI de TimeORM reconoce las configuraciones tipeadas. Ajusta el uso de ts-node para que interprete correctamente decoradores y estructuras modulares.
Migraciones no generadas: Si encuentras que no hay cambios detectados, verifica si las tablas fueron creadas manualmente. Si es así, elimínalas y vuelve a generar las migraciones para que el CLI las reconozca.
¿Cómo asegurarnos de que las migraciones corren correctamente?
Finalmente, ejecutar eficazmente las migraciones es vital. Un error común es que no se detecten cambios si las tablas ya existen. Siempre:
Elimina tablas creadas previamente desde la consola de administración antes de generar nuevas migraciones.
Revisa los logs tras ejecutar migraciones para confirmar que no hay errores silenciosos.
Implementa las mejores prácticas, como evitar el uso del modo síncrono en producción, y confía en las migraciones para manejar los datos historiales correctamente. Sigue explorando y configurando, y estarás un paso más cerca de una base de datos robusta y bien gestionada. ¡Ánimo, sigue adelante y mejora cada día!
Configuración y uso de migraciones con TimeORM y TypeScript
Si ingresas al curso recientemente, sobre abril de 2023, te recomiendo que vayas a los módulos 32, 33 y 34 antes de seguir, ya que explican como migrar el proyecto a las versiones más recientes. El módulo 34 se centra en las migraciones. Los cambios son importantes, particularmente con las migraciones de TypeORM, ya que ahora pide configurar un archivo data-source.ts y cambia el script. Hazlo y te ahorraras varias horas de investigación y dolores de cabeza.
Así es. Al parecer se han reducido las opciones a solo una: instalar el CLI, configurar las migraciones y ejecutarlas desde el comando del package json.
Para evitar futuros dolores de cabeza en sus despliegues, traten de definir siempre sus variables de entorno en archivos .env sin dejar espacios antes/después del signo igual:
# Eviten esto 🚫TYPEORM_CONNECTION = postgres
# Así es mejor ✔️TYPEORM_CONNECTION=postgres
Tengo una consulta, al usar migraciones y las variables de entorno para la config de TypeORM, ya no es necesaria la configuracion que se hizo en **database.module.ts ** importando el modulo de TypeOrmModule? Gracias
Básicamente dice que el futuro de TypeORM es incierto, con errores y un mantenimiento muy pobre, otro artìculo sobre el tema está acá. https://news.ycombinator.com/item?id=26888369
Nota: En el curso actual se está utilizando una versión de TypeORM de 2021. Sin embargo, en 2024, se han implementado cambios en la configuración de TypeORM. Estos cambios se abordan en la siguiente clase: Migraciones en TypeORM - Clase 34. Asegúrate de revisarla para entender cómo aplicar la nueva configuración correctamente.
migrations:['./src/database/migrations/*.ts']// Esta opción lo que hace es que indica en donde se han de leer las migraciones, no en donde TypeORM debería de ponerlas
Usar la terminología de whatever.whatever en el archivo que se va a generar (./migrations/current.migration como puse arriba), genera un error en el CLI de TypeORM, esa terminación debe de ir sin puntos o en cambio con barra al piso "_"
Como se muestra en esta documentación, se puede especificar más bien poco al objeto de Data Source
"typeorm":"typeorm-ts-node-commonjs -d src/database/dataSource.ts","migration:generate":"npm run typeorm migration:generate src/database/initaltables"
Y finalmente correr:
npm run migration:generate
La configuración dada por el profesor dejó de funcionar a partir de la versión 0.3 de typeorm según hilos de issues de github.
La forma en cómo lo resolví fue la siguiente:
Instalé ts-node y typeorm
npm i typeorm
npm install ts-node --save-dev
Creé un archivo donde instancié la clase Datasource en la carpeta config
Tomar nota que las rutas entities y migrations debe ser acorde a cómo tienen organizadas las carpetas de su proyecto
Configuré package json
"typeorm":"typeorm-ts-node-esm","migration:generate":"npm run typeorm migration:generate -- -d src/config/typeOrm.config-migrations.ts src/database/migrations/migration",
Lo que todavía me hace falta mejorar es que todavía no puedo darle un nombre a los archivos dinámicamente.
Tomar nota que para correr el comando migration:generate debe estar encendida la base de datos para recibir peticiones.
Fuentes:
Issue Github
Documentación oficial
Les dejo mi versión del archivo typeorm.config.ts:
Y no olviden instalar el ts-node porque con eso fue que me dio.
Configurando el CLI para migraciones (Actual)
Crear un archivo con una instancia de DataSource
Veamos cómo configurar el CLI de TypeORM para trabajar con migraciones en nuestro proyecto utilizando un archivo de instancia de DataSource.
Crear un archivo con una instancia de DataSource: Para comenzar, crearemos un archivo llamado dataSource.ts en la carpeta src/database. Aquí está un ejemplo de cómo se podría configurar este archivo:
import{DataSource}from'typeorm';import{ config }from'dotenv';import{ConfigService}from'@nestjs/config';config();const configService =newConfigService();// creamos una nueva instancia de DataSource con un objeto de configuraciónexportdefaultnewDataSource({ type:'postgres', username: configService.get('POSTGRES_USER'), password: configService.get('POSTGRES_PASSWORD'), database: configService.get('POSTGRES_DB'), port: configService.get('POSTGRES_PORT'), host: configService.get('POSTGRES_HOST'), synchronize:false, logging:true,// entidades que va a leer entities:['src/*/*/*.entity.ts'],// donde leerá las migraciones migrations:['src/database/migrations/*.ts'],// nombre de la tabla de migraciones migrationsTableName:'migrations',});
Cambios en los comandos del CLI: Ahora, necesitaremos actualizar los comandos en el archivo package.json para reflejar los cambios en el CLI de TypeORM.
{"scripts":{"typeorm":"typeorm-ts-node-commonjs -d src/database/dataSource.ts","migration:generate":"npm run typeorm migration:generate src/database/migrations/migration"}}
En los comandos actualizados:
El comando typeorm se ha cambiado a typeorm-ts-node-commonjs para trabajar con TypeScript en lugar de JavaScript común.
El comando migration:generate ahora requiere el uso del flag -dataSource seguido de la ruta al archivo dataSource.ts que hemos creado.
Es importante tener en cuenta que ahora ya no se utiliza el flag -n para indicar el nombre del archivo de migración. En su lugar, al ejecutar el comando migration:generate, debemos especificar la ruta y el nombre del archivo de migración, que en mi caso lo hago de forma automática desde el package.json.
Para crear la migración ejecutamos el siguiente comando:
npm run migration:generate
Y listo, así es como creamos la configuración para generar migraciones.
El curso está algo desfasado, pero a mí me dio con esto 👇🏻
Primero hice una instalación del paquete ts-node como dev:
yarn add ts-node -D
Cree un archivo typeorm.config.ts dentro del src, con lo siguiente:
y finalmente correrlo en la terminal de la siguiente forma
npm run migration:generate -- src/database/migrations/init
y eso me genero mi migración, espero les sirva
Este aspecto de TypeORM es un desastre, para la quien esté usando la versión: 9.0.1 de TypeORM, la forma de poder conectar a una base de datos, ahora es usando un objeto por aparte llamado 'DataSource' que ha de exportarse, el archivo que le contiene puede poner en cualquier lugar, pero TypeORM por defecto lo genera en la ruta ./src/data-source.ts, por lo que si se pone con ese nombre en esa ruta lo va a poder encontrar por defecto, si se desea o necesita; también se puede especificar un path a ese archivo, por ejemplo: './src/database/dataSource.ts' (Ahí lo puse yo), el archivo dataSource.ts debería contener esto:
Para no hard codear las variables de entorno se puede usar dotenv que se instala al instalar @nest/config, como se ve en un comentario de esta guía
Sin embargo, la opción migrations: ['./src/database/migrations/*.ts'] realmente no hace nada, pues en la documentación de TypeORM (El décimo ejemplo), en el ejemplo de este apartado simpre especifican el path en donde se ha de crear el archivo de migraciones:
O bien sin poner la ruta ./migrations/current.migration, porque de esa manera se hace menos incómodo de buscar luego, pero toca redactar a mano la ruta en donde se va generar la migración
Tengo el mismo problema, si es cuestión de la versión, pero no logro configurar que el CLI tome las variables de entorno, y no me parece correcto hacer un downgrade de la versión
cli-ts-node-commonjs.js migration:generate <path>Generates a newmigration file with sql needs to be executed to update schema.Opciones:-h,--help Muestra ayuda [booleano]-d,--dataSource Path to the file where your DataSource instance is
defined.[cadena de caracteres][requerido]-p,--pretty Pretty-print generated SQL[booleano][defecto:false]-o,--outputJs Generate a migration file on Javascript instead ofTypescript[booleano][defecto:false]--dr,--dryrun Prints out the contents of the migration instead of writing it to a file [booleano][defecto:false]--ch,--check Verifies that the current database is up to date and that
no migrations are needed.Otherwise exits with code 1.[booleano][defecto:false]-t,--timestamp Custom timestamp for the migration name
[número][defecto:false]-v,--version Muestra número de versión [booleano]Hacen falta argumentos no-opcionales:Número recibido 0, necesita por lo menos 1