#Что означает ошибка
ERROR: relation "users" does not exist
ERROR: relation "users" does not exist в PostgreSQL означает, что таблица, представление или последовательность с таким именем не найдены в путях поиска схем. Причины: другая база или схема, регистр и кавычки в имени, миграции не выполнены.
PostgreSQL приводит неэкранированные имена к нижнему регистру.
Таблица "Users" и users — разные объекты.
Таблица не найдена: она в другой схеме, имя набрано с другим регистром либо миграции не выполнены. Проверьте схему (search_path) и регистр имён.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Таблица в другой схеме | Объект находится в схеме, отсутствующей в search_path | Укажите явное имя schema.table либо исправьте согласованный search_path. |
| Регистр имени | Имя создано в кавычках с заглавными буквами | Используйте точный регистр и кавычки; не переименовывайте объект вслепую. |
| Не выполнены миграции | Таблица отсутствует в нужной базе и миграции не применялись | Проверить историю миграций, затем применить на тестовой копии. |
| Подключение не к той базе | current_database() отличается от базы приложения | Исправьте строку подключения, не создавайте новую таблицу в чужой базе. |
#Пошаговое решение
- Проверьте текущую базу и схемуОткройте SQL-клиент именно для приложения, где ошибка (
psql, pgAdmin или IDE) и сначала выполнитеSELECT current_database(), current_schema(), current_user; SHOW search_path;. Сверьте имя базы, пользовательскую роль и окружение с настройками подключения приложения (тест/разработка/рабочая база).relation does not existможет относиться не только к таблице, но и к представлению, индексу или последовательности. Не создавайте новую таблицу до выяснения, куда направлен запрос. - Найдите таблицу в information_schemaВ psql выполните
\dt *.*для видимых таблиц либо SQLSELECT table_schema, table_name FROM information_schema.tables WHERE table_name ILIKE '%users%' ORDER BY 1,2;, заменивusersна часть имени. Если объект нашёлся в схеме, отличной от ожидаемой, в запросе укажитеschema.tableили исправьте согласованную настройкуsearch_path; глобально менять search_path в рабочей базе без проверки опасно. Если объект не найден, убедитесь, что у роли есть доступ и что вы в нужной базе. - Проверьте регистр и кавычкиЕсли объект создан в кавычках с заглавными буквами (например,
CREATE TABLE "Users"), обращаться к нему нужно с теми же кавычками и регистром:SELECT * FROM public."Users" LIMIT 1;. Не путайте это с обычнымusers: PostgreSQL приводит некавыченные идентификаторы к нижнему регистру. Не переименовывайте таблицу в рабочей базе сразу: это может нарушить существующие запросы и внешние зависимости. - Выполните миграцииЕсли в верной базе таблицы действительно нет, проверьте журнал развёртывания и применённых миграций своего проекта (Django
showmigrations, Alembiccurrent, Laravelmigrate:status— используйте только подходящий инструмент). Сначала проверьте резервную копию и актуальную схему, выполните миграцию на тестовой базе, затем по согласованию на рабочей. Не создавайте таблицы вручную «на глаз» и не запускайте миграции в чужой базе. - Проверьте права на схему и таблицуЕсли таблица обнаружена, но доступ не подтверждён, от имени той же роли запустите
SELECT * FROM schema.table LIMIT 1;, подставив точные имена.permission denied for schemaилиpermission denied for table— другая ошибка: администратор может проверить\dp schema.tableи выдать минимально необходимыеUSAGEна схему иSELECT/INSERTтолько по потребности. Повторите исходный запрос в приложении; при сохранении ошибки зафиксируйте SQL, подключённую базу и пользователя. - SQL на просмотр в фактической базе приложения; %users% замените на имя своей таблицыLinux · Терминал (Bash)КомандаSQL на просмотр в фактической базе приложения; %users% замените на имя своей таблицы.
SELECT current_database(), current_schema(), current_user;SHOW search_path;SELECT table_schema, table_name FROM information_schema.tables WHERE table_name ILIKE '%users%';
#База и схема
Проверьте, что подключились к нужной базе: SELECT current_database(), current_schema();. В psql: \c имя_базы, \dt *.* или \dt public.*. Поиск таблицы: SELECT table_schema, table_name FROM information_schema.tables WHERE table_name ILIKE '%users%';. Если таблица в другой схеме, укажите schema.users или настройте SET search_path TO myschema, public;.
#Регистр и кавычки
Если таблица создана как "Users" (в кавычках), обращаться нужно только так: SELECT * FROM "Users";. Для ORM проверьте имя таблицы в модели (Django db_table, Sequelize tableName, Prisma @@map). Лучше использовать нижний регистр без кавычек. Проверьте опечатки и множественное число.
#Миграции и права
Миграции выполняйте только для правильной базы и конкретного проекта, изучив текущее состояние схемы и создав резервную копию. Примеры команд фреймворков — альтернативы, их нельзя запускать подряд. Если объект существует, но доступ запрещён, администратор предоставляет минимальные права на конкретную схему и таблицу, а не GRANT SELECT ON ALL TABLES всем приложением.
SELECT current_database(), current_schema(), current_user;SHOW search_path;SELECT table_schema, table_name FROM information_schema.tables WHERE table_name ILIKE '%users%';