Error de PostgreSQL: column does not exist
ERROR: column "createdat" does not exist
LINE 1: SELECT createdAt FROM users;
^
HINT: Perhaps you meant to reference the column "users.createdAt".
PostgreSQL no pudo resolver un nombre de columna — y muy a menudo el HINT ya te está diciendo por qué. Mira el ejemplo: la consulta dice createdAt, el error dice "createdat", el hint ofrece "users.createdAt". Esa es la regla de plegado a minúsculas en acción.
Qué significa este error
Dos reglas de SQL producen casi todos estos errores:
- Los identificadores sin comillas se pliegan a minúsculas. Una columna creada como
"createdAt"(entrecomillada — los ORM y las herramientas GUI adoran hacer esto) solo puede referenciarse como"createdAt". ElcreatedAtsin comillas significacreatedat, un nombre distinto. - Las comillas dobles delimitan identificadores, las comillas simples delimitan cadenas.
WHERE name = "alice"no compara contra la cadena 'alice' — busca una columna llamadaalice, y falla con exactamente este error.
Causas comunes
- Columna con mayúsculas/minúsculas creada con comillas, referenciada sin ellas (o viceversa).
- Comillas dobles usadas para un literal de cadena — la pista es que la "columna faltante" es un valor de datos.
- Un alias de SELECT usado en
WHERE: los alias no son visibles ahí (la cláusula WHERE se evalúa antes que la lista de selección).SELECT price * qty AS total ... WHERE total > 100falla. - Deriva de schema: la columna genuinamente no existe en este entorno porque una migración no se ha ejecutado.
Cómo diagnosticarlo
\d users -- nombres y mayúsculas/minúsculas EXACTAS de las columnas
Compara carácter por carácter, incluidas las mayúsculas/minúsculas. Si la consulta la genera un ORM, registra el SQL real — el entrecomillado que emite el ORM es toda la historia.
Cómo solucionarlo
- Problema de mayúsculas/minúsculas → entrecomíllalo exactamente (
"createdAt") — o acaba con el dolor para siempre:
Identificadores en minúsculas snake_case, nunca entrecomillados, es la convención que evita esta clase de bug por completo.ALTER TABLE users RENAME COLUMN "createdAt" TO created_at; - Literal de cadena → comillas simples:
WHERE name = 'alice'. - Alias en WHERE → repite la expresión, o envuelve la consulta:
SELECT * FROM (SELECT price * qty AS total ...) t WHERE total > 100.
🔍
Las mismas reglas, edición tabla: relation does not exist — search_path e identificadores entrecomillados.
