PostgreSQL-Fehler: relation does not exist
ERROR: relation "users" does not exist
LINE 1: SELECT * FROM users;
^
PostgreSQL fand unter den Schemas, in die es schauen darf, keine Tabelle, View oder Sequenz mit diesem Namen. In der Praxis bedeutet dieser Fehler selten, dass die Tabelle fehlt — meist bedeutet er, dass Sie und PostgreSQL an unterschiedlichen Orten suchen.
Was dieser Fehler bedeutet
"Relation" ist PostgreSQLs Oberbegriff für Tabellen, Views, Sequenzen, Indizes und Verwandte. Die Namensauflösung hängt von zwei Kontexten ab, die die Leute vergessen zu haben: die aktuelle Datenbank (Relationen leben pro Datenbank; es gibt keinen datenbankübergreifenden Zugriff) und den search_path, die geordnete Liste von Schemas, gegen die ein unqualifizierter Name aufgelöst wird.
Dazu eine Syntaxregel, die endlose Verwirrung stiftet: nicht in Anführungszeichen gesetzte Bezeichner werden in Kleinbuchstaben umgewandelt. Eine als "Users" (gequotet, von einem ORM oder GUI) erstellte Tabelle kann nur je als "Users" erreicht werden — der ungequotete Name users ist ein anderer Bezeichner.
Häufige Ursachen
- Die Tabelle liegt in einem Schema, das nicht auf Ihrem
search_pathsteht (z. B. ist esapp.usersund Ihr Pfad ist"$user", public). - Gemischt-groß-/kleingeschriebener Bezeichner, mit Anführungszeichen erstellt; ungequotete Queries werden in Kleinbuchstaben umgewandelt und verfehlen ihn.
- Falsche Datenbank — verbunden mit der Standarddatenbank
postgresstatt der der Anwendung; alles "verschwindet". - Migrationen in dieser Umgebung nicht angewendet, oder auf ein anderes Schema angewendet, als die App abfragt.
- Eine temporäre Tabelle aus einer anderen Sitzung oder einer früheren Verbindung (Temp-Tabellen sind pro Sitzung).
So diagnostizieren Sie ihn
SELECT current_database();
SHOW search_path;
-- Existiert die Relation irgendwo, in welcher Groß-/Kleinschreibung auch immer?
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%';
Diese letzte Query klärt es in einem Zug: sie sagt Ihnen, ob die Relation überhaupt existiert, in welchem Schema und mit welcher genauen Groß-/Kleinschreibung.
So beheben Sie ihn
- Falsches Schema → qualifizieren Sie den Namen (
app.users) oder setzen Sie den Pfad dauerhaft dort, wohin er gehört:
(EinALTER ROLE app_user SET search_path = app, public; -- oder: ALTER DATABASE appdb SET search_path = app, public;SET search_pathauf Sitzungsebene funktioniert auch, aber mit Connection-Poolern sind Einstellungen auf Rollen-/Datenbankebene vorzuziehen.) - Gemischte Schreibweise → quoten Sie exakt (
SELECT * FROM "Users") — und übernehmen Sie die Konvention, die allen hilft: nur kleingeschriebene, ungequotete Bezeichner. - Falsche Datenbank → korrigieren Sie den Connection-String;
psqlohne Datenbanknamen verbindet Sie mit einer nach Ihrem OS-Benutzer benannten oder mitpostgres— selten das, was die App verwendet. - Fehlende Migrationen → führen Sie sie aus; die obige Diagnose-Query bestätigt, ob das Schema wirklich leer ist.
