Troubleshoot — Anti-Patterns and Verification
Common issues, incompatible types, and the verification checklist for PostgreSQL schemas used as external databases for NocoDB and NocoBase.
Incompatible SQL Types
These PostgreSQL types are not supported by NocoDB. Use the replacements.
| Type |
Replacement |
VARCHAR(255)[], any ARRAY[] |
json |
POINT, PATH, POLYGON, CIRCLE |
json (coordinates as [x, y]) |
PostgreSQL ENUM type |
text + SingleSelect in UI |
INHERITS (table inheritance) |
Regular tables + FK |
Common Anti-Patterns
| Problem |
Solution |
| Spaces in column names |
Use snake_case |
Reserved words (order, user) |
Add suffix: sort_order, app_user |
DEFAULT on json column |
Don't set it — set default in the application |
| PK without auto-increment |
Always use serial or bigserial |
jsonb instead of json |
Use json — safer for both platforms |
| UUID as primary key |
Use serial / bigserial — NocoDB expects auto-increment |
| Missing FK constraint |
Always add ALTER TABLE ... ADD CONSTRAINT for every relation |
| Missing index on FK column |
Always CREATE INDEX on every FK column |
Junction table with separate id |
Use composite PK from both FK columns (NocoDB style) |
ON DELETE CASCADE on FK |
Use ON DELETE NO ACTION (NocoDB default) |
Verification Checklist
Run through this checklist before connecting your database to NocoDB or NocoBase:
Diagnostic Queries
Run these queries to find schema issues before connecting to NocoDB or NocoBase.
-- Find tables without a serial/bigserial PK
SELECT t.table_name, c.column_name, c.data_type
FROM information_schema.tables t
JOIN information_schema.columns c ON t.table_name = c.table_name
WHERE t.table_schema = 'public'
AND c.column_name = 'id'
AND c.column_default NOT LIKE 'nextval%';
-- Find FK columns without indexes
SELECT tc.table_name, kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema = 'public'
AND NOT EXISTS (
SELECT 1 FROM pg_indexes
WHERE tablename = tc.table_name
AND indexdef LIKE '%' || kcu.column_name || '%'
);
-- Find ENUM columns (must be replaced with text)
SELECT c.table_name, c.column_name, c.udt_name
FROM information_schema.columns c
WHERE c.table_schema = 'public'
AND c.data_type = 'USER-DEFINED'
AND c.udt_name IN (
SELECT t.typname FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
GROUP BY t.typname
);
-- Find ARRAY columns (must be replaced with json)
SELECT table_name, column_name, data_type, udt_name
FROM information_schema.columns
WHERE table_schema = 'public'
AND data_type = 'ARRAY';
-- Find jsonb columns (should be replaced with json)
SELECT table_name, column_name
FROM information_schema.columns
WHERE table_schema = 'public'
AND data_type = 'jsonb';
1---2name: troubleshoot-273description: This skill should be used when the user asks about "incompatible types", "what to avoid", "schema checklist", "NocoDB doesn't recognize", "NocoBase can't read", "ARRAY not working", "ENUM alternative", "naming conventions", "validation checklist", or encounters issues with a PostgreSQL schema connected to NocoDB or NocoBase.4---56# Troubleshoot — Anti-Patterns and Verification78Common issues, incompatible types, and the verification checklist for PostgreSQL schemas used as external databases for NocoDB and NocoBase.910## Incompatible SQL Types1112These PostgreSQL types are **not supported** by NocoDB. Use the replacements.1314| Type | Replacement |15|------|-------------|16| `VARCHAR(255)[]`, any `ARRAY[]` | `json` |17| `POINT`, `PATH`, `POLYGON`, `CIRCLE` | `json` (coordinates as `[x, y]`) |18| PostgreSQL `ENUM` type | `text` + SingleSelect in UI |19| `INHERITS` (table inheritance) | Regular tables + FK |2021## Common Anti-Patterns2223| Problem | Solution |24|---------|----------|25| Spaces in column names | Use `snake_case` |26| Reserved words (`order`, `user`) | Add suffix: `sort_order`, `app_user` |27| `DEFAULT` on `json` column | Don't set it — set default in the application |28| PK without auto-increment | Always use `serial` or `bigserial` |29| `jsonb` instead of `json` | Use `json` — safer for both platforms |30| UUID as primary key | Use `serial` / `bigserial` — NocoDB expects auto-increment |31| Missing FK constraint | Always add `ALTER TABLE ... ADD CONSTRAINT` for every relation |32| Missing index on FK column | Always `CREATE INDEX` on every FK column |33| Junction table with separate `id` | Use composite PK from both FK columns (NocoDB style) |34| `ON DELETE CASCADE` on FK | Use `ON DELETE NO ACTION` (NocoDB default) |3536## Verification Checklist3738Run through this checklist before connecting your database to NocoDB or NocoBase:3940- [ ] PK: `serial` or `bigserial` with name `id`41- [ ] FK columns: type matches parent PK (`int4` for `serial`, `int8` for `bigserial`)42- [ ] FK constraints: `ON DELETE NO ACTION ON UPDATE NO ACTION`43- [ ] Index on every FK column44- [ ] One-to-One: `UNIQUE` on FK column45- [ ] Junction tables: composite PK from two FKs + FK constraints + indexes46- [ ] No `ARRAY[]`, `ENUM`, `POINT`, `POLYGON`, `INHERITS`47- [ ] JSON stored as `json` (not `jsonb`)48- [ ] Select/MultiSelect stored as `text`49- [ ] Names in `snake_case`, no reserved words5051## Diagnostic Queries5253Run these queries to find schema issues before connecting to NocoDB or NocoBase.5455```sql56-- Find tables without a serial/bigserial PK57SELECT t.table_name, c.column_name, c.data_type58FROM information_schema.tables t59JOIN information_schema.columns c ON t.table_name = c.table_name60WHERE t.table_schema = 'public'61 AND c.column_name = 'id'62 AND c.column_default NOT LIKE 'nextval%';6364-- Find FK columns without indexes65SELECT tc.table_name, kcu.column_name66FROM information_schema.table_constraints tc67JOIN information_schema.key_column_usage kcu68 ON tc.constraint_name = kcu.constraint_name69WHERE tc.constraint_type = 'FOREIGN KEY'70 AND tc.table_schema = 'public'71 AND NOT EXISTS (72 SELECT 1 FROM pg_indexes73 WHERE tablename = tc.table_name74 AND indexdef LIKE '%' || kcu.column_name || '%'75 );7677-- Find ENUM columns (must be replaced with text)78SELECT c.table_name, c.column_name, c.udt_name79FROM information_schema.columns c80WHERE c.table_schema = 'public'81 AND c.data_type = 'USER-DEFINED'82 AND c.udt_name IN (83 SELECT t.typname FROM pg_type t84 JOIN pg_enum e ON t.oid = e.enumtypid85 GROUP BY t.typname86 );8788-- Find ARRAY columns (must be replaced with json)89SELECT table_name, column_name, data_type, udt_name90FROM information_schema.columns91WHERE table_schema = 'public'92 AND data_type = 'ARRAY';9394-- Find jsonb columns (should be replaced with json)95SELECT table_name, column_name96FROM information_schema.columns97WHERE table_schema = 'public'98 AND data_type = 'jsonb';99```