· 10 years ago · Sep 23, 2016, 09:24 AM
1### Insert foreign keys into dropped_foreign_keys and drop constraints
2
3Use the following code.
4
5```sql
6create table if not exists dropped_foreign_keys (
7 seq bigserial primary key,
8 sql text
9);
10
11do $$ declare t record;
12 begin
13 for t in select conrelid::regclass::varchar table_name, conname constraint_name,
14 pg_catalog.pg_get_constraintdef(r.oid, true) constraint_definition
15 from pg_catalog.pg_constraint r
16 where r.contype = 'f'
17 -- NOTE: Current schema only:
18 and r.connamespace = (select n.oid from pg_namespace n where n.nspname = current_schema())
19 loop
20 insert into dropped_foreign_keys (sql) values (
21 format('alter table %s add constraint %s %s',
22 t.table_name, quote_ident(t.constraint_name), t.constraint_definition));
23
24 execute format('alter table %s drop constraint %s', t.table_name, quote_ident(t.constraint_name));
25 end loop;
26 end $$;
27```
28
29### Run your sql migrations
30
31NOTE: In your sql migrations make you disable the triggers, run your migrations, and then reenable the triggers. Like below.
32
33```sql
34alter table "User" disable trigger all;
35alter table "SomeOtherTable" disable trigger all;
36insert into "User" ("id", "name") values ("Petesta");
37-- .
38-- .
39-- .
40insert into "SomeOtherTable" ("id", "key") values ("some_random_string");
41alter table "SomeOtherTable" disbale trigger all;
42alter table "User" disable trigger all;
43```
44
45## Add in constraints from the dropped_foreign_keys table
46
47```sql
48do $$ declare t record;
49 begin
50 -- NOTE: Order by seq for easier troubleshooting when data does not satisfy FKs
51 for t in select * from dropped_foreign_keys order by seq loop
52 execute t.sql;
53 delete from dropped_foreign_keys where seq = t.seq;
54 end loop;
55 end $$;
56```
57
58### Last step is to now use setval to set sequence value
59
60Keeps track of the last autoincremented key for each table.
61
62```sql
63-- If you have a table named `User` then you'll want use setval like below
64-- NOTE: Use your table name in place of `User`
65select setval('"User_id_seq"', max(id)) from "User";
66select setval('"SomeOtherTable_id_seq"', max(id)) from "SomeOtherTable";
67```