Base de datos en la sombra y discrepancia en la nomenclatura de Prisma: Un manual de operaciones
Por qué Prisma Migrate Dev solicita restablecer la base de datos, cómo configurar una base de datos de sombra segura y cómo mapear la convención de mayúsculas/minúsculas de Prisma a snake_case en Postgres.
Existen dos quejas que surgen una y otra vez cuando los equipos adoptan Prisma con PostgreSQL: la herramienta de migración sigue ofreciendo borrar la base de datos de desarrollo, y las tablas que crea no se parecen en nada a los nombres que usaría un administrador de Postgres. Ambos son comportamientos documentados, no signos de que Prisma sea inadecuado para producción. Esta guía explica qué ocurre en cada caso y le proporciona un conjunto breve de reglas que mantienen intactos sus datos y sus convenciones de esquema.
Por qué prisma migrate dev ofrece restablecer su base de datos
El incidente típico se presenta así: alguien ejecuta npx prisma migrate dev, el comando se detiene con un error indicando que una tabla o enum “ya existe”, y la forma más rápida de hacer desaparecer ese mensaje parece ser prisma migrate reset. Ese comando elimina todas las tablas y vuelve a ejecutar toda la historia de migraciones desde cero.
Para qué sirve la base de datos sombra
Durante el desarrollo, Prisma Migrate utiliza una segunda base de datos temporal llamada base de datos sombra. Su única función es detectar cambios en la estructura de la base de datos. Cada vez que se ejecuta migrate dev, Prisma crea una base de datos sombra limpia, aplica todos los archivos de migración a ella, analiza el esquema resultante y lo compara con la base de datos de desarrollo real.
Cuando ambos no coinciden, algo ha modificado la base de datos de desarrollo fuera del historial de migraciones. Las causas más comunes son:
- un
prisma db pushque modificó tablas sin crear un archivo de migración - una edición manual realizada a través de un cliente SQL
- un archivo de migración creado por un compañero de equipo que nunca se commitió
Prisma no puede saber qué versión de la verdad deseas conservar, por lo que propone la única opción automática segura que tiene para una base de datos de desarrollo: eliminarla y reconstruirla a partir de las migraciones.
El modo de fallo que no está bien documentado
Lo que sorprende a los equipos es otro problema que produce síntomas similares. En servicios gestionados de Postgres como Neon o Supabase, el usuario de la base de datos en tu cadena de conexión a menudo carece de permisos para crear y eliminar bases de datos según sea necesario. Prisma, entonces, no puede crear su base de datos temporal y falla debido a un error de permisos.
Los desarrolladores suelen interpretar ese error como “las migraciones están dañadas” y, siguiendo los consejos de los hilos de la comunidad, ejecutan migrate reset para solucionarlo. Eso es peligroso, ya que el comando reset destruye los datos de forma fiable si la cadena de conexión apunta a una ubicación real. Las discusiones públicas en GitHub incluyen exactamente esta historia: un error en la base de datos secundaria, un reset no planificado como “solución” y tablas perdidas en medio de un proyecto.
Reglas que mantienen seguras las migraciones
- Asigne a Prisma una base de datos de sombra dedicada. Establezca
shadowDatabaseUrlen una base de datos separada donde sus usuarios puedan crear y eliminar tablas libremente. Nunca lo dirija hacia la base de producción ni hacia una base de pruebas compartida. Dependiendo de su versión de Prisma, esta configuración se encuentra en la configuración de fuentes de datos del archivo de esquema o en el archivo de configuración de Prisma; por lo tanto, consulte la documentación actual para saber dónde la exige su versión. - Considere siempre que
migrate resetes una acción destructiva. Si se sugiere como primer paso para solucionar problemas, deténgase y examine primero las credenciales, los permisos y cualquier desviación en el estado de la base de datos. - Entienda que la producción es diferente.
prisma migrate deploysolo aplica las migraciones pendientes. Nunca crea una base de datos de sombra ni solicita un restablecimiento. El comportamiento de restablecimiento forma parte, por diseño, del flujo de trabajo de desarrollo.
Modelos en PascalCase frente a tablas en snake_case
El segundo punto de fricción es la nomenclatura. El lenguaje de esquemas de Prisma recomienda nombres de modelo en PascalCase y nombres de campos en camelCase, lo cual coincide con las convenciones habituales de JavaScript y TypeScript. En el mundo de Postgres, por lo general se espera lo contrario: identificadores en snake_case, a menudo con nombres de tablas en plural.
Con la configuración por defecto, un modelo llamado User con un campo firstName se convierte en una tabla llamada User con una columna llamada firstName. Postgres acepta esto, pero los identificadores con mayúsculas y minúsculas mezcladas deben ir entre comillas dobles en SQL sin formato, lo cual resulta extraño para los DBAs, las herramientas de generación de informes y cualquier servicio que lea la base de datos sin pasar por Prisma.
Mapeo de nombres con @map y @@map
Prisma resuelve esto con dos atributos: @map renombra la columna de un campo individual, y @@map renombra la tabla detrás de un modelo. Tu código en TypeScript mantiene user.firstName, mientras que la base de datos almacena users.first_name. La asignación funciona bien, pero no se aplica automáticamente. Tienes dos opciones:
- Anotar cada campo y modelo a mano, lo cual es tedioso pero completamente explícito y fácil de revisar
- Usar la herramienta externa
prisma-case-formatCLI, que reescribe en masa la mayúscula y minúscula de los archivos de esquema y puede ejecutarse nuevamente para evitar que los campos nuevos vuelvan a sus valores predeterminados
Cualquiera que sea tu elección, decídela antes de la primera migración. Renombrar tablas y columnas más tarde implica escribir migraciones que afecten los datos existentes, y todas las consultas SQL en bruto del código deben modificarse junto con ellas.
Cómo maneja Drizzle el mismo problema
Drizzle, la alternativa más destacada basada en TypeScript, ofrece una configuración casing que convierte los nombres de tipo camelCase en el código a nombres de tipo snake_case en la base de datos, aplicándolo a todo el esquema. Este es un caso raro en el que la situación habitual se invierte. Por lo general, Prisma se describe como la herramienta más abstracta y Drizzle como la más cercana a SQL; sin embargo, el esquema basado en código de Drizzle facilitó la gestión global del formato de nombres, mientras que el lenguaje de esquema separado de Prisma dejó la opción global como una solicitud de funcionalidad pendiente desde hace tiempo al momento de escribir este texto.
Puntos clave
- Un mensaje de reinicio desde
migrate devindica un desvío o un problema con los permisos de la base de datos sombra, y no migraciones dañadas. - Configure una base de datos sombra explícita e independiente para cualquier proveedor alojado de Postgres.
migrate reset como solución genérica; las implementaciones en producción dependen de migrate deploy, el cual no puede restablecer nada.@map y @@map (de forma manual o con prisma-case-format) antes de su primera migración, y no después.Si está comparando Prisma con Drizzle de manera más amplia, nuestra comparación sobre SQL sin procesamiento, Prisma y Drizzle aborda los aspectos a considerar en esta elección.
Lecturas relacionadas
- Exploración de MovieVault: Una API de lista de vigilancia con Express 5, Prisma 7 y JWT — Una especificación de ejercicio full-stack con tiempo limitado y su backend basado en Express, Prisma y JWT, con notas de revisión sobre verificaciones de propiedad, efectos en cadena y manejo de errores.
- Configuración de Prisma 7 con PostgreSQL en un proyecto TypeScript Node.js — Solución de los errores comunes al configurar Prisma 7 en TypeScript, desde URLs inválidas o indefinidas hasta problemas con rootDir, y conexión de PostgreSQL mediante el adaptador del controlador pg.