Skip to content

Instantly share code, notes, and snippets.

@mikecebul
Created September 25, 2024 18:29
Show Gist options
  • Save mikecebul/5b5d9d2758fa4acd00c6ca9a92dfc8e3 to your computer and use it in GitHub Desktop.
Save mikecebul/5b5d9d2758fa4acd00c6ca9a92dfc8e3 to your computer and use it in GitHub Desktop.
How to migrate a collection table to use a different foreign key
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-sqlite'
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
await payload.db.drizzle.run(sql`
CREATE TABLE IF NOT EXISTS \"team_temp\" (
\"id\" integer PRIMARY KEY NOT NULL,
\"memberType\" text DEFAULT \'staff\',
\"name\" text,
\"avatar_id\" integer,
\"image_id\" integer,
\"role\" text,
\"qualifications\" text,
\"bio\" text,
\"meta_hide_from_search_engines\" integer DEFAULT false,
\"meta_metadata_title\" text,
\"meta_metadata_image_id\" integer,
\"meta_metadata_description\" text,
\"published_at\" text,
\"slug\" text,
\"slug_lock\" integer DEFAULT true,
\"updated_at\" text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
\"created_at\" text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
\"_status\" text DEFAULT 'draft',
FOREIGN KEY (\"avatar_id\") REFERENCES \"avatars\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"image_id\") REFERENCES \"landscapes\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"meta_metadata_image_id\") REFERENCES \"cards\"(\"id\") ON UPDATE no action ON DELETE set null
);
`)
await payload.db.drizzle.run(sql`
INSERT INTO \"team_temp\" (
\"id\",
\"memberType\",
\"name\",
\"avatar_id\",
\"image_id\",
\"role\",
\"qualifications\",
\"bio\",
\"meta_hide_from_search_engines\",
\"meta_metadata_title\",
\"meta_metadata_image_id\",
\"meta_metadata_description\",
\"published_at\",
\"slug\",
\"slug_lock\",
\"updated_at\",
\"created_at\",
\"_status\"
)
SELECT
\"id\",
\"memberType\",
\"name\",
\"avatar_id\",
NULL AS \"image_id\",
\"role\",
\"qualifications\",
\"bio\",
\"meta_hide_from_search_engines\",
\"meta_metadata_title\",
\"meta_metadata_image_id\",
\"meta_metadata_description\",
\"published_at\",
\"slug\",
\"slug_lock\",
\"updated_at\",
\"created_at\",
\"_status\"
FROM \"team\";
`)
await payload.db.drizzle.run(sql`DROP TABLE IF EXISTS \"team\";`)
await payload.db.drizzle.run(sql`
ALTER TABLE \"team_temp\" RENAME TO \"team\";
`)
// Create indexes for team_temp table
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team_slug_idx\" ON \"team\" (\"slug\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team_created_at_idx\" ON \"team\" (\"created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team__status_idx\" ON \"team\" (\"_status\");`)
// Do the same for the versions table
await payload.db.drizzle.run(sql`
CREATE TABLE \"_team_v_temp\" (
\"id\" integer PRIMARY KEY NOT NULL,
\"parent_id\" integer,
\"version_memberType\" text DEFAULT 'staff',
\"version_name\" text,
\"version_avatar_id\" integer,
\"version_image_id\" integer,
\"version_role\" text,
\"version_qualifications\" text,
\"version_bio\" text,
\"version_meta_hide_from_search_engines\" integer DEFAULT false,
\"version_meta_metadata_title\" text,
\"version_meta_metadata_image_id\" integer,
\"version_meta_metadata_description\" text,
\"version_published_at\" text,
\"version_slug\" text,
\"version_slug_lock\" integer DEFAULT true,
\"version_updated_at\" text,
\"version_created_at\" text,
\"version__status\" text DEFAULT \'draft\',
\"created_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"updated_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"latest\" integer,
\"autosave\" integer,
FOREIGN KEY (\"parent_id\") REFERENCES \"team\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_avatar_id\") REFERENCES \"avatars\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_image_id\") REFERENCES \"landscapes\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_meta_metadata_image_id\") REFERENCES \"cards\"(\"id\") ON UPDATE no action ON DELETE set null
);
`)
await payload.db.drizzle.run(sql`DROP TABLE \"_team_v\";`)
await payload.db.drizzle.run(sql`ALTER TABLE \"_team_v_temp\" RENAME TO \"_team_v\";`)
// Create indexes for _team_v table
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version_slug_idx\" ON \"_team_v\" (\"version_slug\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version_created_at_idx\" ON \"_team_v\" (\"version_created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version__status_idx\" ON \"_team_v\" (\"version__status\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_created_at_idx\" ON \"_team_v\" (\"created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_updated_at_idx\" ON \"_team_v\" (\"updated_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_latest_idx\" ON \"_team_v\" (\"latest\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_autosave_idx\" ON \"_team_v\" (\"autosave\");`)
}
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
await payload.db.drizzle.run(sql`
CREATE TABLE IF NOT EXISTS \"team_temp\" (
\"id\" integer PRIMARY KEY NOT NULL,
\"memberType\" text DEFAULT 'staff',
\"name\" text,
\"avatar_id\" integer,
\"image_id\" integer,
\"role\" text,
\"qualifications\" text,
\"bio\" text,
\"meta_hide_from_search_engines\" integer DEFAULT false,
\"meta_metadata_title\" text,
\"meta_metadata_image_id\" integer,
\"meta_metadata_description\" text,
\"published_at\" text,
\"slug\" text,
\"slug_lock\" integer DEFAULT true,
\"updated_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"created_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"_status\" text DEFAULT \'draft\',
FOREIGN KEY (\"avatar_id\") REFERENCES \"avatars\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"image_id\") REFERENCES \"landscapes\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"meta_metadata_image_id\") REFERENCES \"cards\"(\"id\") ON UPDATE no action ON DELETE set null
);
`)
await payload.db.drizzle.run(sql`
INSERT INTO \"team_temp\" (
\"id\",
\"memberType\",
\"name\",
\"avatar_id\",
\"image_id\",
\"role\",
\"qualifications\",
\"bio\",
\"meta_hide_from_search_engines\",
\"meta_metadata_title\",
\"meta_metadata_image_id\",
\"meta_metadata_description\",
\"published_at\",
\"slug\",
\"slug_lock\",
\"updated_at\",
\"created_at\",
\"_status\"
)
SELECT
\"id\",
\"memberType\",
\"name\",
\"avatar_id\",
\"image_id\",
\"role\",
\"qualifications\",
\"bio\",
\"meta_hide_from_search_engines\",
\"meta_metadata_title\",
\"meta_metadata_image_id\",
\"meta_metadata_description\",
\"published_at\",
\"slug\",
\"slug_lock\",
\"updated_at\",
\"created_at\",
\"_status\"
FROM \"team\";
`)
await payload.db.drizzle.run(sql`DROP TABLE IF EXISTS \"team\";`)
await payload.db.drizzle.run(sql`ALTER TABLE \"team_temp\" RENAME TO \"team\";`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team_slug_idx\" ON \"team\" (\"slug\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team_created_at_idx\" ON \"team\" (\"created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"team__status_idx\" ON \"team\" (\"_status\");`)
await payload.db.drizzle.run(sql`
CREATE TABLE \"_team_v_temp\" (
\"id\" integer PRIMARY KEY NOT NULL,
\"parent_id\" integer,
\"version_memberType\" text DEFAULT 'staff',
\"version_name\" text,
\"version_avatar_id\" integer,
\"version_image_id\" integer,
\"version_role\" text,
\"version_qualifications\" text,
\"version_bio\" text,
\"version_meta_hide_from_search_engines\" integer DEFAULT false,
\"version_meta_metadata_title\" text,
\"version_meta_metadata_image_id\" integer,
\"version_meta_metadata_description\" text,
\"version_published_at\" text,
\"version_slug\" text,
\"version_slug_lock\" integer DEFAULT true,
\"version_updated_at\" text,
\"version_created_at\" text,
\"version__status\" text DEFAULT \'draft\',
\"created_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"updated_at\" text DEFAULT (strftime(\'%Y-%m-%dT%H:%M:%fZ\', \'now\')) NOT NULL,
\"latest\" integer,
\"autosave\" integer,
FOREIGN KEY (\"parent_id\") REFERENCES \"team\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_avatar_id\") REFERENCES \"avatars\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_image_id\") REFERENCES \"landscapes\"(\"id\") ON UPDATE no action ON DELETE set null,
FOREIGN KEY (\"version_meta_metadata_image_id\") REFERENCES \"cards\"(\"id\") ON UPDATE no action ON DELETE set null
);
`)
await payload.db.drizzle.run(sql`
INSERT INTO \"_team_v_temp\" SELECT * FROM \"_team_v\";
`)
await payload.db.drizzle.run(sql`DROP TABLE \"_team_v\";`)
await payload.db.drizzle.run(sql`ALTER TABLE \"_team_v_temp\" RENAME TO \"_team_v\";`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version_slug_idx\" ON \"_team_v\" (\"version_slug\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version_created_at_idx\" ON \"_team_v\" (\"version_created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_version_version__status_idx\" ON \"_team_v\" (\"version__status\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_created_at_idx\" ON \"_team_v\" (\"created_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_updated_at_idx\" ON \"_team_v\" (\"updated_at\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_latest_idx\" ON \"_team_v\" (\"latest\");`)
await payload.db.drizzle.run(sql`CREATE INDEX IF NOT EXISTS \"_team_v_autosave_idx\" ON \"_team_v\" (\"autosave\");`)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment