如何在不丢失数据的情况下更新Knex.js表字段默认值
如何用Knex.js修改users表profile_image字段的默认值
你说得对,绝对不能修改已经运行过的迁移文件——Knex只会执行一次每个迁移,改了也不会生效,还会导致团队成员之间的迁移状态不一致。正确的做法是创建一个新的迁移文件来修改字段的默认值,这样既不会影响现有数据,也能保持迁移历史的完整性。
下面是具体的操作步骤:
1. 生成新的迁移文件
首先在终端运行Knex的迁移生成命令,给这个迁移起一个清晰的名字,比如:
knex migrate:make update_users_profile_image_default
这个命令会在你的迁移目录下生成一个新的时间戳命名的文件,比如20240520123456_update_users_profile_image_default.js。
2. 编写迁移逻辑
打开这个新生成的文件,编写up和down函数:
基础版:仅修改字段默认值
如果只需要让新插入的记录使用新的默认值,不需要更新现有数据,可以这样写:
exports.up = function(knex) { return knex.schema.alterTable('users', function(table) { // 修改profile_image字段的默认值,注意要加上.alter()方法 table.text('profile_image') .defaultTo('你的新默认图片URL') .alter(); }); }; exports.down = function(knex) { return knex.schema.alterTable('users', function(table) { // 回滚时恢复原来的默认值 table.text('profile_image') .defaultTo('http://www.ecehh.org/wp-content/uploads/2018/02/avatar.jpg') .alter(); }); };
进阶版:同时更新现有旧默认值的记录
如果你想把现有记录中使用旧默认值的profile_image也改成新的,可以用事务来保证操作的原子性:
exports.up = function(knex) { return knex.transaction(async (trx) => { // 第一步:修改字段的默认值 await trx.schema.alterTable('users', function(table) { table.text('profile_image') .defaultTo('你的新默认图片URL') .alter(); }); // 第二步:更新所有使用旧默认值的记录 await trx('users') .where('profile_image', '=', 'http://www.ecehh.org/wp-content/uploads/2018/02/avatar.jpg') .update({ profile_image: '你的新默认图片URL' }); }); }; exports.down = function(knex) { return knex.transaction(async (trx) => { // 回滚时先恢复字段默认值 await trx.schema.alterTable('users', function(table) { table.text('profile_image') .defaultTo('http://www.ecehh.org/wp-content/uploads/2018/02/avatar.jpg') .alter(); }); // 再把之前更新的记录改回去 await trx('users') .where('profile_image', '=', '你的新默认图片URL') .update({ profile_image: 'http://www.ecehh.org/wp-content/uploads/2018/02/avatar.jpg' }); }); };
3. 执行迁移
最后在终端运行命令执行这个新迁移:
knex migrate:latest
这样就完成了字段默认值的修改,既不会丢失现有数据,也符合Knex迁移的最佳实践。
内容的提问来源于stack exchange,提问作者Martin Nordström
相关产品推荐
相关产品推荐

