Find and fix foreign key violations

To check for a foreign key where the corresponding primary key is missing, run the following command:

Code Sample

  
 WITH 
  
 q 
  
 AS 
  
 ( 
  
 SELECT 
  
 conrelid 
 :: 
 regclass 
  
 AS 
  
 fk_table 
 , 
  
  
 confrelid 
 :: 
 regclass 
  
 AS 
  
 pk_table 
 , 
  
  
 format 
 ( 
 '(%s)' 
 ,( 
 select 
  
 string_agg 
 ( 
 format 
 ( 
 'fk.%I' 
 , 
  
 attname 
 ), 
  
 ', ' 
 ) 
  
  
 FROM 
  
 pg_attribute 
  
 a 
  
  
 JOIN 
  
 unnest 
 ( 
 conkey 
 ) 
  
 ia 
 ( 
 nr 
 ) 
  
 ON 
  
 ia 
 . 
 nr 
  
 = 
  
 a 
 . 
 attnum 
  
 WHERE 
  
 attrelid 
  
 = 
  
 conrelid 
 )) 
  
 AS 
  
 fk_fields 
 , 
  
  
 format 
 ( 
 '(%s)' 
 ,( 
 select 
  
 string_agg 
 ( 
 format 
 ( 
 'pk.%I' 
 , 
  
 attname 
 ), 
  
 ', ' 
 ) 
  
  
 FROM 
  
 pg_attribute 
  
 a 
  
  
 JOIN 
  
 unnest 
 ( 
 confkey 
 ) 
  
 ia 
 ( 
 nr 
 ) 
  
 ON 
  
 ia 
 . 
 nr 
  
 = 
  
 a 
 . 
 attnum 
  
 WHERE 
  
 attrelid 
  
 = 
  
 confrelid 
 )) 
  
 AS 
  
 pk_fields 
 , 
  
  
 pg_get_constraintdef 
 ( 
 oid 
 ) 
  
 FROM 
  
 pg_constraint 
  
 WHERE 
  
 contype 
 = 
 'f' 
  
 ) 
  
 SELECT 
  
 format 
 ( 
  
 $ 
 sql 
 $ 
  
 DO 
  
 $$ 
  
 BEGIN 
  
 RAISE 
  
 NOTICE 
  
 'checking Foreign Key %3$s%1$s ==> %4$s%2$s' 
 ; 
  
 END 
 ; 
 $$ 
 ; 
  
 SELECT 
  
 % 
 1 
 $ 
 s 
 , 
  
 % 
 2 
 $ 
 s 
  
  
 FROM 
  
 % 
 3 
 $ 
 s 
  
 AS 
  
 fk 
  
 LEFT 
  
 JOIN 
  
 % 
 4 
 $ 
 s 
  
 AS 
  
 pk 
  
 ON 
  
 % 
 1 
 $ 
 s 
  
 = 
  
 % 
 2 
 $ 
 s 
  
  
 WHERE 
  
 % 
 2 
 $ 
 s 
  
 IS 
  
 NULL 
  
 AND 
  
 % 
 1 
 $ 
 s 
  
 IS 
  
 NOT 
  
 NULL 
  
 /* any NULL on FK side bypasses FK constraint by design */ 
  
 /* use limit for testing, or detecting that "there is a problem in this table */ 
  
 --  LIMIT 10 
  
 $ 
 sql 
 $ 
 , 
  
 fk_fields 
 , 
  
 pk_fields 
 , 
  
 fk_table 
 , 
  
 pk_table 
  
 ) 
  
 FROM 
  
 q 
  
 \ 
 gexec 
  

The output of the script will be similar to the following. If there is no output, there are no violations and you have successfully rebuilt your index.

Output

  
id  
 | 
  
pk_id  
  
----+-------  
 | 
  
 4 
  
 ( 
 1 
  
row ) 
  

In the above output, the first column shows the primary key columns, in this example, a column named id . The second column is the referencing column for the foreign key. This means there is a row, pk_id=4 , for which a parent primary key doesn't exist. You can decide if these keys are valid and if they are not, you can delete them.

Design a Mobile Site
View Site in Mobile | Classic
Share by: