Rails迁移:检查存在并继续进行?

Dan*_*ark 72 migration ruby-on-rails

我在迁移中做了这样的事情:

add_column :statuses, :hold_reason, :string rescue puts "column already added"
Run Code Online (Sandbox Code Playgroud)

但事实证明,虽然这适用于SQLite,但它不适用于PostgreSQL.看起来如果add_column爆炸,即使捕获了Exception,事务也已经死了,因此Migration不能做任何额外的工作.

是否有任何非DB特定方法来检查列或表是否已存在?如果做不到的话,有没有办法让我的救援块真正起作用?

Tob*_*hen 162

从Rails 3.0及更高版本开始,您可以使用它column_exists?来检查列的存在性.

unless column_exists? :statuses, :hold_reason
  add_column :statuses, :hold_reason, :string
end
Run Code Online (Sandbox Code Playgroud)

还有一个table_exists?功能,可以追溯到Rails 2.1.

  • 如果我在change方法中定义它,这是否适用于回滚? (4认同)
  • 是的,回滚将是一个问题......我们不确定是否应该删除该列......因为我们没有记录以前的状态。 (2认同)

Rad*_*eth 13

Rails 6.1+:

add_column :statuses, :hold_reason, :string, if_not_exists: true
Run Code Online (Sandbox Code Playgroud)

https://github.com/rails/rails/pull/38352/files

导轨 < 6.1:

add_column :statuses, :hold_reason, :string unless column_exists?(:statuses, :hold_reason)
Run Code Online (Sandbox Code Playgroud)


SG *_* 86 7

甚至更短

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
Run Code Online (Sandbox Code Playgroud)