This commit is contained in:
84
scripts/animaldex-uuid-to-serial.sql
Normal file
84
scripts/animaldex-uuid-to-serial.sql
Normal file
@@ -0,0 +1,84 @@
|
||||
-- One-off: convert animaldex ids from uuid to serial, keeping existing rows.
|
||||
-- Postgres can't cast uuid -> integer, so db:push can't do this itself.
|
||||
--
|
||||
-- Run BEFORE re-running db:push, once per database:
|
||||
-- psql "$DB_URL" -v ON_ERROR_STOP=1 -f scripts/animaldex-uuid-to-serial.sql
|
||||
--
|
||||
-- Safe to run on an empty database too. Everything is in one transaction, so a
|
||||
-- failure leaves the database untouched.
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- the failed push created this before erroring out
|
||||
DROP SEQUENCE IF EXISTS animals_id_seq;
|
||||
|
||||
-- 1. new integer ids alongside the uuid ones
|
||||
ALTER TABLE animals ADD COLUMN new_id serial;
|
||||
ALTER TABLE sightings ADD COLUMN new_id serial;
|
||||
ALTER TABLE photos ADD COLUMN new_id serial;
|
||||
|
||||
-- 2. translate the foreign keys through the uuid -> integer mapping
|
||||
ALTER TABLE sightings ADD COLUMN new_animal_id integer;
|
||||
UPDATE sightings s SET new_animal_id = a.new_id FROM animals a WHERE a.id = s.animal_id;
|
||||
|
||||
ALTER TABLE photos ADD COLUMN new_sighting_id integer;
|
||||
UPDATE photos p SET new_sighting_id = s.new_id FROM sightings s WHERE s.id = p.sighting_id;
|
||||
|
||||
-- 3. drop the old foreign keys (names vary by how they were created)
|
||||
DO $$
|
||||
DECLARE r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT conrelid::regclass AS tbl, conname
|
||||
FROM pg_constraint
|
||||
WHERE contype = 'f' AND conrelid IN ('sightings'::regclass, 'photos'::regclass)
|
||||
LOOP
|
||||
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname);
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
-- 4. swap the foreign key columns
|
||||
ALTER TABLE photos DROP COLUMN sighting_id;
|
||||
ALTER TABLE photos RENAME COLUMN new_sighting_id TO sighting_id;
|
||||
ALTER TABLE photos ALTER COLUMN sighting_id SET NOT NULL;
|
||||
|
||||
ALTER TABLE sightings DROP COLUMN animal_id;
|
||||
ALTER TABLE sightings RENAME COLUMN new_animal_id TO animal_id;
|
||||
ALTER TABLE sightings ALTER COLUMN animal_id SET NOT NULL;
|
||||
|
||||
-- 5. swap the primary keys
|
||||
DO $$
|
||||
DECLARE r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT conrelid::regclass AS tbl, conname
|
||||
FROM pg_constraint
|
||||
WHERE contype = 'p'
|
||||
AND conrelid IN ('animals'::regclass, 'sightings'::regclass, 'photos'::regclass)
|
||||
LOOP
|
||||
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %I', r.tbl, r.conname);
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
ALTER TABLE animals DROP COLUMN id;
|
||||
ALTER TABLE animals RENAME COLUMN new_id TO id;
|
||||
ALTER TABLE animals ADD PRIMARY KEY (id);
|
||||
ALTER SEQUENCE animals_new_id_seq RENAME TO animals_id_seq;
|
||||
|
||||
ALTER TABLE sightings DROP COLUMN id;
|
||||
ALTER TABLE sightings RENAME COLUMN new_id TO id;
|
||||
ALTER TABLE sightings ADD PRIMARY KEY (id);
|
||||
ALTER SEQUENCE sightings_new_id_seq RENAME TO sightings_id_seq;
|
||||
|
||||
ALTER TABLE photos DROP COLUMN id;
|
||||
ALTER TABLE photos RENAME COLUMN new_id TO id;
|
||||
ALTER TABLE photos ADD PRIMARY KEY (id);
|
||||
ALTER SEQUENCE photos_new_id_seq RENAME TO photos_id_seq;
|
||||
|
||||
-- 6. restore the foreign keys under the names drizzle expects
|
||||
ALTER TABLE sightings ADD CONSTRAINT sightings_animal_id_animals_id_fkey
|
||||
FOREIGN KEY (animal_id) REFERENCES animals(id) ON DELETE CASCADE;
|
||||
ALTER TABLE photos ADD CONSTRAINT photos_sighting_id_sightings_id_fkey
|
||||
FOREIGN KEY (sighting_id) REFERENCES sightings(id) ON DELETE CASCADE;
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user