The Error
ERROR: relation "table_name" does not exist
LINE 1: SELECT * FROM table_name;
^
Running a query you know should work โ and PostgreSQL says the table doesn't exist. You can see it right there in pgAdmin. Four things cause this almost every time, and none of them mean your data is gone.
Why This Happens
PostgreSQL found your query but can't resolve the table reference. The table might be perfectly intact. The problem is usually one of these:
- The table lives in a different schema and your
search_pathskips it - Case sensitivity โ the table was created with a quoted mixed-case name like
"Users" - You're connected to the wrong database (happens constantly in multi-environment setups)
- The table genuinely doesn't exist โ the migration never ran, or ran against the wrong environment
- It's a temporary table from another session โ temp tables are session-scoped and invisible elsewhere
Step-by-Step Fix
Step 1: Check If the Table Actually Exists
Before anything else, confirm the table is actually there:
-- List all tables across all schemas
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_name = 'your_table_name';
Or in psql:
\dt *.*
No results? The table doesn't exist. Check your migration files or run the CREATE TABLE statement manually.
Step 2: Check Your Schema and Search Path
PostgreSQL defaults to looking in the public schema. Many production setups use custom schemas โ app, api, reporting โ and if search_path doesn't include them, every query against those tables fails with this error.
-- See current search path
SHOW search_path;
-- See which schema you're in right now
SELECT current_schema();
Table is in a schema called app? Three options:
-- Option A: Prefix the table name explicitly
SELECT * FROM app.users;
-- Option B: Add schema to search path for this session
SET search_path TO app, public;
SELECT * FROM users;
-- Option C: Make it permanent for the current user
ALTER ROLE your_user SET search_path TO app, public;
Step 3: Check for Case Sensitivity
This one catches everyone eventually. PostgreSQL lowercases all unquoted identifiers โ so Users, users, and USERS all resolve to the same thing. The exception: tables created with double quotes.
-- Created like this:
CREATE TABLE "Users" (id serial, name text);
-- This FAILS (PostgreSQL looks for lowercase "users"):
SELECT * FROM users;
-- This WORKS:
SELECT * FROM "Users";
Find the exact stored name:
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public';
Mixed-case names in the results mean quoting them in every single query. The easier long-term fix: stick to lowercase with underscores when creating tables โ user_accounts, not UserAccounts.
Step 4: Make Sure You're in the Right Database
Each PostgreSQL database is completely isolated. A table in db_production is invisible from a connection to db_staging โ even on the same server. This is a classic trap in Docker and CI pipelines where DATABASE_URL quietly points somewhere unexpected.
-- Check current database
SELECT current_database();
-- In psql, switch database (requires reconnection)
\c correct_database_name
Using a connection string in your app? Double-check the database name in your .env or config file.
Step 5: Check If It's a View or Sequence
The same error fires when referencing a missing view or sequence. Search across all object types at once:
SELECT schemaname, tablename, 'table' AS type FROM pg_tables WHERE tablename = 'target_name'
UNION ALL
SELECT schemaname, viewname, 'view' FROM pg_views WHERE viewname = 'target_name'
UNION ALL
SELECT schemaname, sequencename, 'sequence' FROM pg_sequences WHERE sequencename = 'target_name';
Verify the Fix
Quick sanity check after making changes:
-- Should return rows or an empty set โ not an error
SELECT * FROM your_schema.your_table LIMIT 5;
-- Confirm you're in the right schema and database
SELECT current_schema(), current_database();
Changed search_path for a role? Disconnect and reconnect to confirm it persists.
Quick Tips
- Name tables in lowercase with underscores โ
user_orders, not"UserOrders". Eliminates case sensitivity issues permanently. - Explicit schema prefixes (
schema.table) are more reliable thansearch_path, especially in app code that runs across multiple environments. - Before running migrations, run
SELECT current_database(), current_schema();to confirm you're targeting the right place. - In Docker or CI, a misconfigured
DATABASE_URLpointing to the wrong database is the #1 cause of this error outside local development. - Django and SQLAlchemy both support explicit schema config โ check
Meta.db_tableor__table_args__if queries work in psql but fail in your app.

