如何在不执行迁移的情况下从Rails Migration文件提取RAW SQL
在不执行数据库迁移的前提下从Rails Migration提取原生SQL
方法一:通过控制台拦截SQL执行
直接在Rails控制台中加载迁移文件,拦截数据库连接的执行方法,记录生成的SQL而不实际执行迁移:
# 加载目标迁移文件,替换为你的迁移文件名 require Rails.root.join('db/migrate/20230918004257_add_some_column_to_table.rb') # 初始化数组存储SQL语句 captured_sql = [] # 备份原execute方法,替换为仅记录SQL的逻辑 original_execute = ActiveRecord::Base.connection.method(:execute) ActiveRecord::Base.connection.define_singleton_method(:execute) do |sql, *args| captured_sql << sql # 返回空结果集避免报错 OpenStruct.new(rows: [], fields: []) end # 执行迁移的change方法 AddSomeColumnToTable.new.change # 恢复原execute方法 ActiveRecord::Base.connection.define_singleton_method(:execute, original_execute) # 输出捕获到的原生SQL puts captured_sql.join("\n")
执行后就能得到对应迁移的原生SQL,对应示例会输出:
ALTER TABLE `table` ADD `column_a` varchar(255) COMMENT 'column a'; ALTER TABLE `table` ADD `column_b` varchar(255) COMMENT 'column b'; ALTER TABLE `table` ADD `column_c` varchar(255) COMMENT 'column c';
方法二:使用迁移dry-run模式+日志过滤
直接通过终端执行迁移的dry-run命令,该模式会输出将要执行的SQL但不实际修改数据库,再通过日志过滤提取目标SQL:
# 执行dry-run迁移,输出所有执行细节并过滤出核心SQL rails db:migrate --dry-run --trace | grep -E "ALTER TABLE|CREATE TABLE|DROP TABLE"
这个方法适合快速提取批量迁移的SQL,不需要编写控制台代码。
注意事项
- 生成的SQL会匹配当前Rails配置的数据库(MySQL/PostgreSQL等),不同数据库的SQL语法会有差异
- 如果迁移中包含复杂逻辑(如条件判断、自定义SQL),需要确保拦截逻辑覆盖到所有执行路径
内容的提问来源于stack exchange,提问作者jeyraof
相关产品推荐
相关产品推荐

