{"id":13106,"date":"2019-11-28T07:39:25","date_gmt":"2019-11-28T06:39:25","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/"},"modified":"2019-11-28T07:39:25","modified_gmt":"2019-11-28T06:39:25","slug":"enabling-disabling-and-validating-foreign-key-constraints-in-postgresql","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/","title":{"rendered":"Enabling, disabling, and validating foreign key constraints in PostgreSQL"},"content":{"rendered":"<p>Constraints are in important concept in every realtional database system and they guarantee the correctness of your data. While constraints are essentials there are situations when it is required to disable or drop them temporarily. The reason could be performance related because it is faster to validate the constraints at once after a data load. The reason could also be, that you need to load data and you do not know if the data is ordered in such a way that all foreign keys will validate for the time the data is loaded. In such a case it is required to either drop the constraints or to disable them until the data load is done. Validation of the constraints is deferred until all your data is there.<\/p>\n<p><!--more--><\/p>\n<p>As always lets start with a simple test case, two tables, the second one references the first one:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# create table t1 ( a int primary key\npostgres(#                 , b text\npostgres(#                 , c date\npostgres(#                 );\nCREATE TABLE\npostgres=# create table t2 ( a int primary key\npostgres(#                 , b int references t1(a)\npostgres(#                 , c text\npostgres(#                 );\nCREATE TABLE\n<\/pre>\n<p>Two rows, for each of them:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# insert into t1 (a,b,c) values(1,'aa',now());\nINSERT 0 1\npostgres=# insert into t1 (a,b,c) values(2,'bb',now());\nINSERT 0 1\npostgres=# insert into t2 (a,b,c) values (1,1,'aa');\nINSERT 0 1\npostgres=# insert into t2 (a,b,c) values (2,2,'aa');\n<\/pre>\n<p>Currently the two tiny tables look like this:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# d t1\n                 Table \"public.t1\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | text    |           |          | \n c      | date    |           |          | \nIndexes:\n    \"t1_pkey\" PRIMARY KEY, btree (a)\nReferenced by:\n    TABLE \"t2\" CONSTRAINT \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a)\n\npostgres=# d t2\n                 Table \"public.t2\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | integer |           |          | \n c      | text    |           |          | \nIndexes:\n    \"t2_pkey\" PRIMARY KEY, btree (a)\nForeign-key constraints:\n    \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a)\n\npostgres=# \n<\/pre>\n<p>Lets assume we want to load some data provided by a script. As we do not know the ordering of the data in the script we decide to disable the foreign key constraint on the t2 table and validate it after the load:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 disable trigger all;\nALTER TABLE\n<\/pre>\n<p>The syntax might look a bit strange but it actually does disable the foreign key and it would have disabled all the foreign keys if there would have been more than one. It becomes more clear when we look at the table again:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1; highlight: [13,14]\">\npostgres=# d t2\n                 Table \"public.t2\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | integer |           |          | \n c      | text    |           |          | \nIndexes:\n    \"t2_pkey\" PRIMARY KEY, btree (a)\nForeign-key constraints:\n    \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a)\nDisabled internal triggers:\n    \"RI_ConstraintTrigger_c_16460\" AFTER INSERT ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE FUNCTION \"RI_FKey_check_ins\"()\n    \"RI_ConstraintTrigger_c_16461\" AFTER UPDATE ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE FUNCTION \"RI_FKey_check_upd\"()\n<\/pre>\n<p>&#8220;ALL&#8221; means, please also disable the internal triggers that are responsible for verifying the constraints. One restriction of the &#8220;ALL&#8221; keyword is, that you need to be superuser for doing that. Trying that with a normal user will fail:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# create user u1 with login password 'u1';\nCREATE ROLE\npostgres=# c postgres u1\nYou are now connected to database \"postgres\" as user \"u1\".\npostgres=&gt; create table t3 ( a int primary key\npostgres(&gt;                 , b text\npostgres(&gt;                 , c date\npostgres(&gt;                 );\nCREATE TABLE\npostgres=&gt; create table t4 ( a int primary key\npostgres(&gt;                 , b int references t3(a)\npostgres(&gt;                 , c text\npostgres(&gt;                 );\nCREATE TABLE\npostgres=&gt; alter table t4 disable trigger all;\nERROR:  permission denied: \"RI_ConstraintTrigger_c_16484\" is a system trigger\npostgres=&gt; \n<\/pre>\n<p>What you could do as a regular user to do disable the user triggers:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=&gt; alter table t4 disable trigger user;\nALTER TABLE\n<\/pre>\n<p>As I do not have any triggers it of course does not make much sense. Coming back to our initial t1 and t2 tables. As the foreign key currently is disabled we can insert data into the t2 table that would violate the constraint:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# select * from t1;\n a | b  |     c      \n---+----+------------\n 1 | aa | 2019-11-27\n 2 | bb | 2019-11-27\n(2 rows)\n\npostgres=# select * from t2;\n a | b | c  \n---+---+----\n 1 | 1 | aa\n 2 | 2 | aa\n(2 rows)\n\npostgres=# insert into t2 (a,b,c) values (3,3,'cc');\nINSERT 0 1\npostgres=# \n<\/pre>\n<p>There clearly is no matching parent for this row in the t1 table but the insert succeeds, as the foreign key is disabled. Time to validate the constraint:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# d t2\n                 Table \"public.t2\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | integer |           |          | \n c      | text    |           |          | \nIndexes:\n    \"t2_pkey\" PRIMARY KEY, btree (a)\nForeign-key constraints:\n    \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a)\nDisabled internal triggers:\n    \"RI_ConstraintTrigger_c_16460\" AFTER INSERT ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE FUNCTION \"RI_FKey_check_ins\"()\n    \"RI_ConstraintTrigger_c_16461\" AFTER UPDATE ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE FUNCTION \"RI_FKey_check_upd\"()\n\npostgres=# alter table t2 enable trigger all;\nALTER TABLE\npostgres=# d t2\n                 Table \"public.t2\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | integer |           |          | \n c      | text    |           |          | \nIndexes:\n    \"t2_pkey\" PRIMARY KEY, btree (a)\nForeign-key constraints:\n    \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a)\n\npostgres=# alter table t2 validate constraint t2_b_fkey;\nALTER TABLE\npostgres=# \n<\/pre>\n<p>Surprise, surprise, PostgreSQL does not complain about the invalid row. Why is that? If we ask the <a href=\"https:\/\/www.postgresql.org\/docs\/current\/catalog-pg-constraint.html\" target=\"_blank\" rel=\"noopener noreferrer\">pg_constraint<\/a> catalog table the constraint is recorded as validated:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# select convalidated from pg_constraint where conname = 't2_b_fkey' and conrelid = 't2'::regclass;\n convalidated \n--------------\n t\n(1 row)\n<\/pre>\n<p>It is even validated if we disable it once more:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 disable trigger all;\nALTER TABLE\npostgres=# select convalidated from pg_constraint where conname = 't2_b_fkey' and conrelid = 't2'::regclass;\n convalidated \n--------------\n t\n(1 row)\n<\/pre>\n<p>That implies that PostgreSQL will not validate the constraint when we enable the internal triggers and PostgreSQL will not validate all the data as long as the status is valid. What we really need to do for getting the constraint validated is to invalidate it before:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 alter CONSTRAINT t2_b_fkey not valid;\nERROR:  ALTER CONSTRAINT statement constraints cannot be marked NOT VALID\n<\/pre>\n<p>Seems this is not the correct way of doing it. The correct way of doing it is to drop the foreign key and then re-create it with status invalid:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 drop constraint t2_b_fkey;\nALTER TABLE\npostgres=# delete from t2 where a in (3,4);\nDELETE 2\npostgres=# alter table t2 add constraint t2_b_fkey foreign key (b) references t1(a) not valid;\nALTER TABLE\npostgres=# d t2\n                 Table \"public.t2\"\n Column |  Type   | Collation | Nullable | Default \n--------+---------+-----------+----------+---------\n a      | integer |           | not null | \n b      | integer |           |          | \n c      | text    |           |          | \nIndexes:\n    \"t2_pkey\" PRIMARY KEY, btree (a)\nForeign-key constraints:\n    \"t2_b_fkey\" FOREIGN KEY (b) REFERENCES t1(a) NOT VALID\n<\/pre>\n<p>Now we have the desired state and we can insert our data:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# insert into t2(a,b,c) values (3,3,'cc');\nERROR:  insert or update on table \"t2\" violates foreign key constraint \"t2_b_fkey\"\nDETAIL:  Key (b)=(3) is not present in table \"t1\".\n<\/pre>\n<p>Surprise, again. Creating a &#8220;not valid&#8221; constraint only tells PostgreSQL not to scan the whole table to validate if all the rows are valid. For data inserted or updated the constraint is still checked, and this is why the insert fails.<\/p>\n<p>What options do we have left? The obvious one is this:<\/p>\n<ul>\n<li>Drop all the foreign the keys.<\/li>\n<li>Load the data.<\/li>\n<li>Re-create the foreign keys, but leave them invalid to avoid the costly scan of the tables. Now data will be validated.<\/li>\n<li>Validate the constraints when there is less load on the system.<\/li>\n<\/ul>\n<p>Another possibility would be this:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 alter constraint t2_b_fkey deferrable;\nALTER TABLE\npostgres=# begin;\nBEGIN\npostgres=# set constraints all deferred;\nSET CONSTRAINTS\npostgres=# insert into t2 (a,b,c) values (3,3,'cc');\nINSERT 0 1\npostgres=# insert into t2 (a,b,c) values (4,4,'dd');\nINSERT 0 1\npostgres=# insert into t1 (a,b,c) values (3,'cc',now());\nINSERT 0 1\npostgres=# insert into t1 (a,b,c) values (4,'dd',now());\nINSERT 0 1\npostgres=# commit;\nCOMMIT\n<\/pre>\n<p>The downside of this is that this only works until the next commit, so you have to do all your work in one transaction. The key point of this post is, that the assumption that following will validate your data is false:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# alter table t2 disable trigger all;\nALTER TABLE\npostgres=# insert into t2 (a,b,c) values (5,5,'ee');\nINSERT 0 1\npostgres=# alter table t2 enable trigger all;\nALTER TABLE\npostgres=# \n<\/pre>\n<p>This will only validate new data but it does not guarantee that all the rows satisfy the constraint:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# insert into t2 (a,b,c) values (6,6,'ff');\nERROR:  insert or update on table \"t2\" violates foreign key constraint \"t2_b_fkey\"\nDETAIL:  Key (b)=(6) is not present in table \"t1\".\npostgres=# select * from t2 where b = 5;\n a | b | c  \n---+---+----\n 5 | 5 | ee\n(1 row)\n\npostgres=# select * from t1 where a = 5;\n a | b | c \n---+---+---\n(0 rows)\n<\/pre>\n<p>Finally: There is another way of doing it, but this directly updates the pg_constraint catalog table and this is something you should _not_ do (never update internal tables directly!):<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\npostgres=# delete from t2 where b = 5;\nDELETE 1\npostgres=# delete from t2 where b = 5;\nDELETE 1\npostgres=# alter table t2 disable trigger all;\nALTER TABLE\npostgres=# insert into t2 values (5,5,'ee');\nINSERT 0 1\npostgres=# alter table t2 enable trigger all;\nALTER TABLE\npostgres=# update pg_constraint set convalidated = false where conname = 't2_b_fkey' and conrelid = 't2'::regclass;\nUPDATE 1\npostgres=# alter table t2 validate constraint t2_b_fkey;\nERROR:  insert or update on table \"t2\" violates foreign key constraint \"t2_b_fkey\"\nDETAIL:  Key (b)=(5) is not present in table \"t1\".\npostgres=# \n<\/pre>\n<p>In this case the constraint will be fully validated as it is recorded as invalid in the catalog.<\/p>\n<p>Conclusion: Do not rely on assumptions, always carefully test your procedures.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Constraints are in important concept in every realtional database system and they guarantee the correctness of your data. While constraints are essentials there are situations when it is required to disable or drop them temporarily. The reason could be performance related because it is faster to validate the constraints at once after a data load. [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229],"tags":[77],"type_dbi":[],"class_list":["post-13106","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","tag-postgresql"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Enabling, disabling, and validating foreign key constraints in PostgreSQL - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Enabling, disabling, and validating foreign key constraints in PostgreSQL\" \/>\n<meta property=\"og:description\" content=\"Constraints are in important concept in every realtional database system and they guarantee the correctness of your data. While constraints are essentials there are situations when it is required to disable or drop them temporarily. The reason could be performance related because it is faster to validate the constraints at once after a data load. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-11-28T06:39:25+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Westermann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@westermanndanie\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Westermann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"Enabling, disabling, and validating foreign key constraints in PostgreSQL\",\"datePublished\":\"2019-11-28T06:39:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\"},\"wordCount\":720,\"commentCount\":2,\"keywords\":[\"PostgreSQL\"],\"articleSection\":[\"Database Administration &amp; Monitoring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\",\"name\":\"Enabling, disabling, and validating foreign key constraints in PostgreSQL - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2019-11-28T06:39:25+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Enabling, disabling, and validating foreign key constraints in PostgreSQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\",\"name\":\"Daniel Westermann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"caption\":\"Daniel Westermann\"},\"description\":\"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.\",\"sameAs\":[\"https:\/\/x.com\/westermanndanie\"],\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Enabling, disabling, and validating foreign key constraints in PostgreSQL - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/","og_locale":"en_US","og_type":"article","og_title":"Enabling, disabling, and validating foreign key constraints in PostgreSQL","og_description":"Constraints are in important concept in every realtional database system and they guarantee the correctness of your data. While constraints are essentials there are situations when it is required to disable or drop them temporarily. The reason could be performance related because it is faster to validate the constraints at once after a data load. [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/","og_site_name":"dbi Blog","article_published_time":"2019-11-28T06:39:25+00:00","author":"Daniel Westermann","twitter_card":"summary_large_image","twitter_creator":"@westermanndanie","twitter_misc":{"Written by":"Daniel Westermann","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"Enabling, disabling, and validating foreign key constraints in PostgreSQL","datePublished":"2019-11-28T06:39:25+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/"},"wordCount":720,"commentCount":2,"keywords":["PostgreSQL"],"articleSection":["Database Administration &amp; Monitoring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/","url":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/","name":"Enabling, disabling, and validating foreign key constraints in PostgreSQL - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2019-11-28T06:39:25+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/enabling-disabling-and-validating-foreign-key-constraints-in-postgresql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Enabling, disabling, and validating foreign key constraints in PostgreSQL"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66","name":"Daniel Westermann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","caption":"Daniel Westermann"},"description":"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.","sameAs":["https:\/\/x.com\/westermanndanie"],"url":"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/13106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=13106"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/13106\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=13106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=13106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=13106"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=13106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}