Erreur PostgreSQL : relation does not exist
ERROR: relation "users" does not exist
LINE 1: SELECT * FROM users;
^
PostgreSQL n'a trouvé aucune table, vue ou séquence portant ce nom parmi les schémas où il est autorisé à chercher. En pratique cette erreur signifie rarement que la table manque — elle signifie généralement que vous et PostgreSQL cherchez à des endroits différents.
Ce que signifie cette erreur
« Relation » est le terme générique de PostgreSQL pour les tables, vues, séquences, index et consorts. La résolution des noms dépend de deux éléments de contexte qu'on oublie souvent avoir : la base de données courante (les relations vivent par base ; il n'y a pas d'accès inter-bases) et le search_path, la liste ordonnée des schémas contre lesquels un nom non qualifié est résolu.
Plus une règle de syntaxe qui génère une confusion sans fin : les identifiants sans guillemets sont repliés en minuscules. Une table créée en tant que "Users" (avec guillemets, par un ORM ou une interface graphique) ne peut jamais être atteinte que par "Users" — le nom sans guillemets users est un identifiant différent.
Causes fréquentes
- La table est dans un schéma qui n'est pas sur votre
search_path(par ex. c'estapp.userset votre chemin est"$user", public). - Identifiant à casse mixte créé avec des guillemets ; les requêtes sans guillemets se replient en minuscules et le manquent.
- Mauvaise base — connecté à la base
postgrespar défaut au lieu de celle de l'application ; tout « disparaît ». - Migrations non appliquées dans cet environnement, ou appliquées à un schéma différent de celui que l'application interroge.
- Une table temporaire d'une autre session ou d'une connexion antérieure (les tables temp sont par session).
Comment la diagnostiquer
SELECT current_database();
SHOW search_path;
-- La relation existe-t-elle quelque part, sous n'importe quelle casse ?
SELECT n.nspname AS schema, c.relname, c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ILIKE '%users%';
Cette dernière requête tranche d'un coup : elle vous dit si la relation existe du tout, dans quel schéma, et avec quelle casse exacte.
Comment la corriger
- Mauvais schéma → qualifiez le nom (
app.users) ou définissez le chemin de façon persistante là où il doit l'être :
(LeALTER ROLE app_user SET search_path = app, public; -- ou bien : ALTER DATABASE appdb SET search_path = app, public;SET search_pathau niveau session fonctionne aussi, mais avec des poolers de connexions préférez les réglages au niveau rôle/base.) - Casse mixte → mettez-le entre guillemets exactement (
SELECT * FROM "Users") — et adoptez la convention qui sauve tout le monde : uniquement des identifiants en minuscules, sans guillemets. - Mauvaise base → corrigez la chaîne de connexion ;
psqlsans nom de base vous connecte à une base portant le nom de votre utilisateur OS, oupostgres— rarement celle qu'utilise l'application. - Migrations manquantes → exécutez-les ; la requête de diagnostic ci-dessus confirme si le schéma est réellement vide.
