Rails数据修改迁移执行无报错但数据未变更问题排查
Rails数据迁移执行成功但数据未变更问题排查
问题详情
我用rails g migration FixSourceNames生成了清理数据库数据的迁移,初始结构如下:
class FixSourceNames < ActiveRecord::Migration[7.0] def change end end
修改后的迁移文件:
class FixSourceNames < ActiveRecord::Migration[7.0] def self.up Dataset.where(source: "U.S. Census Bureau American Community Survey").update_all(source: "US Census Bureau American Community Survey") Dataset.where(source: "US Census - American Community Survey").update_all(source: "US Census Bureau American Community Survey") Dataset.where(source: "US Census Bureau - American Community Survey").update_all(source: "US Census Bureau American Community Survey") Dataset.where(source: "HUD Office of Policy Development & Research").update_all(source: "HUD") Dataset.where(source: "CDC - Behavioral Risk Factors Survey").update_all(source: "CDC") Dataset.where(source: "County Health Rankings").update_all(source: "Robert Wood Johnson Foundation/University of Wisconsin") end def self.down end end
执行rake db:migrate显示迁移成功:
% rake db:migrate == 20221216160630 FixSourceNames: migrating =================================== == 20221216160630 FixSourceNames: migrated (0.1593s) ==========================
但数据库数据完全没变化,把这些命令单独放控制台执行却能正常更新数据。我试过指定版本迁移rake db:migrate VERSION=20221216160630,也试过把逻辑写到change方法里,都没用。
可能的原因及解决办法
1. 迁移已被标记为执行,重复执行不生效
Rails会把已完成的迁移记录到schema_migrations表中,只要版本号不变,就算改了迁移内容,再次执行也不会重新运行。
解决步骤:
- 先回滚该迁移:
rake db:rollback VERSION=20221216160630 - 再重新执行:
rake db:migrate VERSION=20221216160630
2. 迁移中使用模型类存在加载问题
迁移执行时,模型可能还没被正确加载,或者模型有未指定的命名空间,导致查询不到数据。
解决办法:改用原生SQL绕开模型依赖,修改迁移为:
class FixSourceNames < ActiveRecord::Migration[7.0] def change execute <<~SQL UPDATE datasets SET source = 'US Census Bureau American Community Survey' WHERE source = 'U.S. Census Bureau American Community Survey'; UPDATE datasets SET source = 'US Census Bureau American Community Survey' WHERE source = 'US Census - American Community Survey'; UPDATE datasets SET source = 'US Census Bureau American Community Survey' WHERE source = 'US Census Bureau - American Community Survey'; UPDATE datasets SET source = 'HUD' WHERE source = 'HUD Office of Policy Development & Research'; UPDATE datasets SET source = 'CDC' WHERE source = 'CDC - Behavioral Risk Factors Survey'; UPDATE datasets SET source = 'Robert Wood Johnson Foundation/University of Wisconsin' WHERE source = 'County Health Rankings'; SQL end end
然后回滚再重新执行迁移。
3. 执行环境与查看数据的环境不匹配
你可能在开发环境执行了迁移,但去看了生产环境的数据库,或者反过来。
解决办法:
- 执行迁移时明确指定环境,比如开发环境:
rake db:migrate RAILS_ENV=development - 确认查看的是对应环境的数据库数据。
4. 查询字符串存在匹配问题
原数据的source字段可能有隐藏字符(比如空格、换行)、大小写差异,或者转义字符不一致(比如迁移里写的&,但数据库里实际是&),导致where条件匹配不到记录。
解决办法:
- 在控制台执行
Dataset.pluck(:source).uniq,导出所有唯一的source值,和迁移里的条件逐一对比,确保字符串完全一致。
内容的提问来源于stack exchange,提问作者guero64
相关产品推荐
相关产品推荐

