-- 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;