web-dev-qa-db-ja.com

postgresqlですべての制約を検証するにはどうすればよいですか?

私はpostgresql 9.3.4のリリースノートに記載されている最初のバグに悩まされているようです: http://www.postgresql.org/docs/devel/static/release-9-3-4。 html

私は今例えば持っています主キーが重複しています。すべての制約(pkeys、fkeys)の再チェックのループを実行する最良の方法は何ですか?>問題の修正->もう一度チェックして、データに問題がないことを確認しますか?

[〜#〜]更新[〜#〜]

私はすべての制約を削除して問題を修正し、次の方法を使用してそれらを再作成するというアプローチを取ることにしました http://blog.hagander.net/archives/131-Automatically-dropping-and-creating- constraint.html 。しかし、私は現在、pkeyを再作成しようとするエラーメッセージに悩まされています。

ERROR:  failed to find parent Tuple for heap-only Tuple at (1192248,5) in table "fruits"
CONTEXT:  SQL statement "ALTER TABLE "pm"."fruits" ADD CONSTRAINT "fruits_pkey" PRIMARY KEY (id)"

これはどういう意味ですか、どうすれば修正できますか(それがオプションである場合は、削除しても問題ありません)?

別の質問:重複する行を削除して削除し、pg_dumpを実行して、そのダンプからデータベースを復元した場合、データは実際にはすべて問題ないでしょうか。データ構造を再構築します-正しいですか?

6
Niels Kristian

さて、テーブル内のすべての外部キーが有効かどうかを確認する方法が必要な場合は、これが役立つ場合があります(スキーマ内のすべての外部キーを検証するだけです)

do $$
  declare r record;
BEGIN 
FOR r IN  (
  SELECT FORMAT(
    'ALTER TABLE %I VALIDATE CONSTRAINT %I;',
    tc.table_name,
    tc.constraint_name
  ) AS x
  FROM information_schema.table_constraints AS tc  
  JOIN information_schema.tables t ON t.table_name = tc.table_name and t.table_type = 'BASE TABLE' 
  JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name 
  JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name 
  WHERE  constraint_type = 'FOREIGN KEY' 
    AND tc.constraint_schema = 'public'
)
  LOOP
    EXECUTE (r.x);  
  END LOOP;
END;
$$;
7
druzin

これはすべての制約で安全に機能します。

SELECT FORMAT(
  'ALTER TABLE %I.%I.%I VALIDATE CONSTRAINT %I;',
  current_database(),
  nsp.nspname,
  cls.relname,
  con.conname
)                                         
FROM pg_constraint AS con
JOIN pg_class AS cls
  ON con.conrelid = cls.oid
JOIN pg_namespace AS nsp
  ON cls.relnamespace = nsp.oid
WHERE convalidated IS FALSE
  -- or delete it for all constraints in all schemas
  AND nsp.nspname = 'mySchema';

それをファイルに保存してQ/Aするか、psql\gexec

2
Evan Carroll

Evan Carroll によって提案された解決策は私にとってはうまくいきませんでした。

すべての制約の前に無効としてマークするようにそれを適応させる必要がありました。

do $$
  declare r record;
BEGIN
FOR r IN  (
  SELECT FORMAT(
    'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I''; ALTER TABLE %I VALIDATE CONSTRAINT %I;',
    tc.constraint_name,
    tc.table_name,
    tc.constraint_name
  ) AS x
  FROM information_schema.table_constraints AS tc
  JOIN information_schema.tables t ON t.table_name = tc.table_name and t.table_type = 'BASE TABLE'
  JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
  JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
  WHERE  constraint_type = 'FOREIGN KEY'
    AND tc.constraint_schema = 'public'
)
  LOOP
    EXECUTE (r.x);
  END LOOP;
END;
$$;
2
Maneki