Skip to content

Instantly share code, notes, and snippets.

@Petesta
Created September 22, 2016 23:59
Show Gist options
  • Save Petesta/bab8feee55fa3501150c815433447288 to your computer and use it in GitHub Desktop.
Save Petesta/bab8feee55fa3501150c815433447288 to your computer and use it in GitHub Desktop.

Insert foreign keys into dropped_foreign_keys and drop constraints

Use the following code.

create table if not exists dropped_foreign_keys (
  seq bigserial primary key,
  sql text
);

do $$ declare t record;
  begin
    for t in select conrelid::regclass::varchar table_name, conname constraint_name,
      pg_catalog.pg_get_constraintdef(r.oid, true) constraint_definition
      from pg_catalog.pg_constraint r
      where r.contype = 'f'
      -- NOTE: Current schema only:
      and r.connamespace = (select n.oid from pg_namespace n where n.nspname = current_schema())
      loop
        insert into dropped_foreign_keys (sql) values (
          format('alter table %s add constraint %s %s',
            t.table_name, quote_ident(t.constraint_name), t.constraint_definition));

        execute format('alter table %s drop constraint %s', t.table_name, quote_ident(t.constraint_name));
      end loop;
  end $$;

Run your sql migrations

NOTE: In your sql migrations make you disable the triggers, run your migrations, and then reenable the triggers. Like below.

alter table "User" disable trigger all;
alter table "SomeOtherTable" disable trigger all;
insert into "User" ("id", "name") values ("Petesta");
-- .
-- .
-- .
insert into "SomeOtherTable" ("id", "key") values ("some_random_string");
alter table "SomeOtherTable" disbale trigger all;
alter table "User" disable trigger all;

Add in constraints from the dropped_foreign_keys table

do $$ declare t record;
  begin
    -- NOTE: Order by seq for easier troubleshooting when data does not satisfy FKs
    for t in select * from dropped_foreign_keys order by seq loop
      execute t.sql;
      delete from dropped_foreign_keys where seq = t.seq;
    end loop;
  end $$;

Last step is to now use setval to set sequence value

Keeps track of the last autoincremented key for each table.

-- If you have a table named `User` then you'll want use setval like below
-- NOTE: Use your table name in place of `User`
select setval('"User_id_seq"', max(id)) from "User";
select setval('"SomeOtherTable_id_seq"', max(id)) from "SomeOtherTable";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment