PostgreSQL error 0A000 (Feature Not Supported) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Remember the unit: PostgreSQL databases are isolated; schemas are the namespace inside one database. If that does not apply, if the tables are in the same database, qualify with schema.table (public.orders), not db.schema.table — the full checklist is below.
SQLSTATE: 0A000
Official name: Feature Not Supported
System name: feature_not_supported
Service: PostgreSQL
The statement used a feature PostgreSQL does not support - most often a three-part cross-database reference such as otherdb.public.table.
You may see this error reported as one of the following messages:
cross-database references are not implemented: "shopdb.public.orders"An app migrated from SQL Server keeps a query written as SELECT * FROM shopdb.public.orders. PostgreSQL parses the first part as a database name and rejects it with SQLSTATE 0A000: cross-database references are not implemented. The table is real and reachable - the syntax simply cannot cross the database boundary, because each PostgreSQL database is a separate storage and namespace island.
Run these to confirm the cause before applying a fix — each command answers a specific question.
SELECT current_database();
\l -- in psql: list all databases
If the target table lives in another listed database, you need fdw/dblink - not a qualified name.
SELECT srvname FROM pg_foreign_server;
An empty result means no fdw is set up yet, which is why the cross-database reference has nothing to resolve to.
Tables in the same database, different schemas?
└─ just qualify: schema.table (works today, no setup)
Different database, same server?
├─ recurring access → postgres_fdw foreign tables (JOIN-able, cached plans)
└─ occasional query → dblink()
Different server entirely?
├─ fdw with a remote host, or
└─ application-level join (two connections, merge in code)
CREATE EXTENSION postgres_fdw;
CREATE SERVER shop_srv FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (dbname 'shopdb', host 'localhost');
CREATE USER MAPPING FOR CURRENT_USER SERVER shop_srv
OPTIONS (user 'reader', password 'secret');
IMPORT FOREIGN SCHEMA public LIMIT TO (orders)
FROM SERVER shop_srv INTO public;
After this, foreign table orders behaves like a local table and can be JOINed - the supported replacement for three-part names.
SELECT *
FROM dblink('dbname=shopdb user=reader password=secret',
'SELECT id, total FROM orders')
AS t(id int, total numeric);
dblink() runs a remote query and returns rows for a single statement - lighter than foreign tables for occasional use.
Use two engines (one per database) and join in Python, or attach the second database via SQLite-style ATTACH only where supported; there is no cross-database FK.
shop = create_engine('postgresql://localhost/shopdb')
with main.connect() as c1, shop.connect() as c2:
orders = pd.read_sql('SELECT * FROM orders', c2)
users = pd.read_sql('SELECT * FROM users', c1)
merged = orders.merge(users, on='user_id')
Configure DATABASES with multiple entries and route each model to its own database; Django never queries across databases in one SQL statement.
# settings.py
DATABASES = {
'default': {...},
'shop': {...},
}
# db_router.py: db_for_read/db_for_write return 'shop' for ShopModel
Most often this happens when writing db.schema.table three-part names carried over from SQL Server or MySQL habits, or when joining a table that lives in a different database on the same server.
Remember the unit: PostgreSQL databases are isolated; schemas are the namespace inside one database.
This page documents fixes for: sqlalchemy, django.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official PostgreSQL documentation linked below and adds practical troubleshooting guidance on top.