Inicio / Artículos

Configuración de Prisma 7 con PostgreSQL en un proyecto Node.js de TypeScript

Corrige los errores comunes de configuración de Prisma 7 en TypeScript, desde URLs inválidas o indefinidas hasta problemas con rootDir, y conecta PostgreSQL mediante el adaptador del controlador pg.

Editor: REACTAPP.TOP7 min de lectura1666 palabras

Fuentes: I Wasted 4 Hours Setting Up Prisma — Here’s How You Should Set Up Prisma v7

Seguir la guía de inicio rápido de Prisma en un proyecto Node.js sencillo de TypeScript a menudo termina con una serie interminable de errores del compilador antes incluso de que se ejecute una sola consulta. Los problemas no radican en los modelos; provienen de la forma en que el compilador de TypeScript, el nuevo archivo de configuración de Prisma y el cliente generado interactúan con una estructura convencional src/dist. Esta guía explica los tres errores más comunes que es probable que encuentres, por qué ocurre cada uno, y un proceso paso a paso para configurarlo con PostgreSQL de manera que se compile sin problemas. Prisma 7 modificó varios valores predeterminados, así que consulta la documentación actual de Prisma en busca de cualquier cambio desde que se redactó este texto.

Los tres errores que arruinan una configuración nueva

Una URL de conexión escrita como cadena de texto o undefined

En prisma.config.ts, la URL de la base de datos se obtiene generalmente con process.env.DATABASE_URL. TypeScript clasifica cada variable de entorno como string | undefined, ya que nada garantiza que esté definida en tiempo de ejecución. La configuración espera un string simple, por lo que el compilador rechaza la asignación.

prisma.config.ts fuera del directorio raíz

Un proyecto típico de TypeScript establece rootDir en src y outDir en dist. Prisma crea prisma.config.ts en la raíz del proyecto, y por defecto el compilador incluye todos los archivos .ts que encuentra. Luego muestra un error indicando que existe un archivo fuera de rootDir que forma parte del programa. Mover la configuración a src silenciaría el error, pero esa no es la solución correcta: src está destinado al código de la aplicación, como rutas, controladores y acceso a datos, no a la configuración de herramientas.

Cliente generado fuera de la carpeta raíz

Ocurre lo mismo con el cliente generado. Si Prisma lo escribe en generated/prisma en la raíz del proyecto, el compilador vuelve a encontrar archivos de TypeScript fuera de rootDir. Mover el código generado a src también es una mala opción, ya que se trata de un resultado del proceso de compilación generado por prisma generate, no de código fuente que se mantenga directamente.

Si no se resuelven, estos errores impiden que el proyecto arranque. Un efecto secundario igualmente molesto es que el JavaScript compilado para prisma.config.ts puede terminar fuera de dist, llenando el repositorio de archivos innecesarios. Corregir los errores uno por uno tiende a generar otros nuevos, por lo que vale la pena arreglar toda la configuración de una vez.

Paso 1: crear el proyecto e instalar las dependencias

Comience con un proyecto vacío de TypeScript. Instale el compilador, tsx para ejecutar TypeScript directamente, y las definiciones de tipo de Node, luego genere un tsconfig.json:

npm init
npm install typescript tsx @types/node --save-dev
npx tsc --init

A continuación, instale Prisma. La CLI y las definiciones de tipo pg son dependencias de desarrollo; el cliente, el adaptador del controlador de PostgreSQL, el controlador pg y dotenv son dependencias en tiempo de ejecución:

npm install prisma @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv

El paquete @prisma/adapter-pg es importante aquí. En Prisma 7 el cliente se comunica con la base de datos a través de un adaptador de controlador en JavaScript, por lo que se le pasa una conexión pg configurada en lugar de depender únicamente de una URL en el esquema.

Paso 2: configurar módulos ES y la estructura del compilador

Marque el paquete como módulo ES en package.json:

{
  "type": "module"
}

Luego establezca las directorios de origen y de salida en tsconfig.json, y cree la carpeta src:

"rootDir": "./src",
"outDir": "./dist",

Paso 3: inicializar Prisma

Ejecute la CLI una vez (por sí sola, esto simplemente muestra los comandos disponibles y confirma que la instalación funciona):

npx prisma

A continuación, inicialice Prisma para PostgreSQL:

npx prisma init --datasource-provider postgresql --output ../generated/prisma

Esto crea prisma.config.ts, una carpeta prisma que contiene schema.prisma, y un archivo .env para la URL de la base de datos. La opción --output determina dónde se generará el cliente; en el Paso 4 se vuelve a revisar esa elección. Justo después de este paso aparecen los errores descritos anteriormente.

Paso 4: corregir la configuración

Tres cambios específicos resuelven los tres errores.

Lea la URL con la herramienta env de Prisma

Sustituya el contenido de prisma.config.ts por el siguiente. Este archivo es en TypeScript, aunque el fragmento esté etiquetado de otra manera.

import "dotenv/config";
import type { PrismaConfig } from "prisma";
import { env } from "prisma/config";

export default {
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
    seed: "tsx prisma/seed.ts",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
} satisfies PrismaConfig;

Aspectos a tener en cuenta:

  • import "dotenv/config" carga .env antes de que nada lo lea. Prisma 7 ya no lo carga automáticamente en esta configuración.
  • env("DATABASE_URL") de prisma/config devuelve un string y genera un error claro si la variable falta, lo que elimina el error string | undefined.
  • satisfies PrismaConfig realiza comprobaciones de tipo en el objeto sin ampliarlo.
  • La configuración también indica dónde se encuentran el esquema y las migraciones, así como qué comando inicializa la base de datos.

Limite lo que incluye el compilador

Agregue una entrada include al final de tsconfig.json:

"include": ["src"],

Esto indica al compilador que genere solo los archivos ubicados en src. La CLI de Prisma sigue leyendo prisma.config.ts por sí sola, pero tsc deja de tratarlo como parte de su programa, por lo que el error rootDir desaparece y no se emite ningún código JavaScript fuera de dist.

Generar el cliente en node_modules

Finalmente, edite schema.prisma para que el generador no tenga una ruta de salida personalizada:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"

Sin un output, el generador prisma-client-js guarda el cliente en node_modules, por lo que nada de lo generado se encuentra en la raíz del proyecto y el error relacionado con rootDir desaparece. El fragmento termina después del provider de la fuente de datos; cierre el bloque con un paréntesis. En Prisma 7, la URL de conexión se encuentra en prisma.config.ts, no en el esquema.

Tenga en cuenta que esto representa un compromiso. El generador más reciente de Prisma, prisma-client, está diseñado para utilizar un directorio de salida explícito, mientras que prisma-client-js es el generador más antiguo. Si adopta el más reciente, mantenga su salida fuera de src y exclúyala de tsc mediante la opción include, como se indicó anteriormente.

Paso 5: agregar la URL de la base de datos e iniciar la migración

Ponga su cadena de conexión en .env. El valor que se muestra a continuación es un marcador de posición; utilice su propia base de datos y nunca guarde valores reales:

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

Defina sus modelos en schema.prisma, luego cree y aplique la primera migración:

npx prisma migrate dev --name init

Paso 6: generar el cliente

Genere el cliente tipado a partir del esquema:

npx prisma generate

Ejecute esto nuevamente cada vez que cambie el esquema, para que los tipos permanezcan sincronizados con sus modelos.

Paso 7: crear una instancia compartida de Prisma

Cree src/lib/prisma.ts para almacenar un único cliente para toda la aplicación. Este archivo crea un adaptador de PostgreSQL a partir de la cadena de conexión y lo pasa a PrismaClient. Este código también está escrito en TypeScript:

import "dotenv/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../../node_modules/@prisma/client/index.js";

const connectionString = `${process.env.DATABASE_URL}`;

const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });

export default prisma;

El cliente se importa mediante una ruta relativa explícita desde node_modules:

import { PrismaClient } from "../../node_modules/@prisma/client/index.js";

Ese camino funciona porque el cliente se generó en node_modules en el Paso 4. En la mayoría de las configuraciones, el especificador simple @prisma/client apunta al mismo paquete, así que pruebe primero con ese; recurre al camino explícito solo si la configuración de resolución de módulos lo requiere.

Un problema en este fragmento: envolver process.env.DATABASE_URL en una cadena de plantilla convierte un valor faltante en el texto literal "undefined", lo que genera un error de conexión confuso posteriormente. Una breve verificación que lance un error cuando la variable esté ausente hace que los fallos sean evidentes.

Ahora importe esta instancia dondequiera que necesite acceso a la base de datos, como en controladores o servicios, y ejecute sus consultas CRUD a través de ella. Mantener un cliente compartido evita abrir un nuevo pool de conexiones por cada archivo.

Puntos clave

  • La mayoría de los errores en la configuración de Prisma 7 con TypeScript provienen de las reglas rootDir del compilador, y no de Prisma en sí.
  • Utilice env() de prisma/config junto con dotenv/config para obtener una URL de base de datos correctamente tipada y cargada explícitamente.
  • Restrinja tsc con "include": ["src"] para que los archivos de herramientas y el código generado no formen parte de la compilación.
  • Mantenga los clientes generados fuera de src, ya sea en node_modules o en una carpeta de salida excluida.
  • Cree un único PrismaClient compartido con el adaptador PrismaPg y valide la cadena de conexión al iniciar.

Si está utilizando Next.js en lugar de un servicio simple de Node.js, nuestra guía para configurar Prisma 7 en un proyecto de Next.js 16 con TypeScript aborda los detalles específicos del framework.

Lecturas relacionadas

  • Desarrollando NestJS en Bun y Prisma 7 para Cloud Run sin los errores de construccion — Un pipeline funcional de GitHub Actions para desplegar una aplicación NestJS en Bun con Prisma 7 y Neon en Cloud Run, además de las soluciones para Docker y los problemas de conexión que dificultan el trabajo del equipo.
  • Exploración de MovieVault: Una API de lista de visionado con Express 5, Prisma 7 y JWT — Una especificación de ejercicio full-stack con plazos establecidos, junto con su backend basado en Express, Prisma y JWT, e información de revisión sobre verificaciones de propiedad, efectos en cadena y manejo de errores.