Some checks failed
Test and deploy staging / staging (push) Has been cancelled
85 lines
3.0 KiB
PL/PgSQL
85 lines
3.0 KiB
PL/PgSQL
-- 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;
|