Fixed performance of column rename migration

- the migration in 5.14 renames the `bio` columns on `members` to `expertise`
- unfortunately, the Knex helper we were using does a lot of interesting
  things with foreign keys that are slow on bigger MySQL clusters, and
  that we don't need here
- this commit refactors the migration to use raw SQL if the DB is MySQL,
  else we use the helper because SQLite SQL might be different here
- I've chosen to only run the renaming functionality if we're in the correct DB
  state to do so (instead of erroring or trying to correct the state)
This commit is contained in:
Daniel Lockyer 2022-09-12 14:01:11 +01:00
parent 352b4ad537
commit 5e4f930ee8
No known key found for this signature in database
GPG Key ID: D21186F0B47295AD

View File

@ -1,34 +1,50 @@
const DatabaseInfo = require('@tryghost/database-info');
const logging = require('@tryghost/logging');
const {createNonTransactionalMigration} = require('../../utils');
module.exports = createNonTransactionalMigration (
module.exports = createNonTransactionalMigration(
async function up(knex) {
// check if the column exists before trying to rename it
logging.info('Renaming members.bio to members.expertise');
const hasBio = await knex.schema.hasColumn('members', 'bio');
const hasExpertise = await knex.schema.hasColumn('members', 'expertise');
if (hasBio && !hasExpertise) {
logging.info('Renaming members.bio to members.expertise');
await knex.schema.table('members', (table) => {
table.renameColumn('bio', 'expertise');
}
);
} else {
logging.info('members.bio does not exist, skipping rename');
// If we don't have the `bio` column, or the `expertise` column already exists, we're
// not in the right state to run this migration
if (!hasBio || hasExpertise) {
logging.warn(`Database is in the wrong state - skipping rename (bio=${hasBio}, expertise=${hasExpertise})`);
return;
}
if (DatabaseInfo.isMySQL(knex)) {
await knex.raw(`ALTER TABLE members CHANGE bio expertise VARCHAR(191) NULL`);
return;
}
await knex.schema.table('members', (table) => {
table.renameColumn('bio', 'expertise');
});
},
async function down(knex) {
logging.info('Renaming members.expertise back to members.bio');
const hasBio = await knex.schema.hasColumn('members', 'bio');
const hasExpertise = await knex.schema.hasColumn('members', 'expertise');
if (hasExpertise && !hasBio) {
logging.info(`Renaming members.expertise to members.bio`);
await knex.schema.table('members', (table) => {
table.renameColumn('expertise', 'bio');
}
);
} else {
logging.warn('members.expertise does not exist, skipping');
// If we already have the `bio` column, or we don't have the `expertise` column, we're
// not in the right state to run this migration
if (hasBio || !hasExpertise) {
logging.warn(`Database is in the wrong state - skipping rename (bio=${hasBio}, expertise=${hasExpertise})`);
return;
}
if (DatabaseInfo.isMySQL(knex)) {
await knex.raw(`ALTER TABLE members CHANGE expertise bio VARCHAR(191) NULL`);
return;
}
await knex.schema.table('members', (table) => {
table.renameColumn('expertise', 'bio');
});
}
);