处理heroku上不存在的表的drop_table迁移

mac*_*ghl 11 postgresql activerecord ruby-on-rails rails-activerecord

我在我的本地环境中的postgres数据库中创建了一个"广告系列"表.我从未犯过这些变化,因此从未将它推到heroku上.

当我改变主意需要该表时,我愚蠢地手动删除了迁移(我知道现在永远不会这样做).但是,由于迁移已经运行,我创建了一个21041211003219_drop_campaigns_table迁移以从本地db中删除表.

现在,当我运行heroku run rake db:migrate生产时,我收到以下错误:

Migrating to DropCampaignsTable (20141211003219)                                                                                                                                                                                                     
== 20141211003219 DropCampaignsTable: migrating ===============================                                                                                                                                                                      
-- drop_table(:campaigns)                                                                                                                                                                                                                            
PG::UndefinedTable: ERROR:  table "campaigns" does not exist                                                                                                                                                                                         
: DROP TABLE "campaigns"                                                                                                                                                                                                                             
rake aborted!                                                                                                                                                                                                                                        
StandardError: An error has occurred, this and all later migrations canceled:                                                                                                                                                                        

PG::UndefinedTable: ERROR:  table "campaigns" does not exist                                                                                                                                                                                         
: DROP TABLE "campaigns"/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'                                                                            
/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `block in execute'             
Run Code Online (Sandbox Code Playgroud)

我知道它正在尝试为一个从未知道存在的表运行drop table迁移,但我不确定如何处理这个问题.

我尝试删除drop table迁移,推送到生产并运行它,但它仍尝试运行该迁移.

在回滚该提交后,我一直在考虑在迁移之前手动创建一个带有日期戳的新迁移 21041211003219_drop_campaigns_table,重新创建表但是我觉得我将留下本地postgres db中存在的表(因为在21041211003219_drop_campaigns_table已经在本地运行).

我是否继续手动创建,然后尝试重新运行drop migration?

有人可以告诉我这里最好的行动方案吗?

amo*_*ebe 27

PG::UndefinedTable: ERROR: table "campaigns" does not exist删除已经不存在的表时,可以通过添加if_exists: truedrop_table以下内容来关闭错误:

def up
  drop_table(:campaigns, if_exists: true)
end
Run Code Online (Sandbox Code Playgroud)

这个选项很少记录,但自2015年初以来就存在于Rails中,我认为它比手工编写SQL更清晰,因为它还处理与各种DB适配器的兼容性.

  • 对我不起作用,但是这样做了:`table_exists?(:campaign)?drop_table(:campaign):nil` (12认同)

mu *_*ort 11

只需删除有问题的迁移,然后继续进行更有趣的事情.显然,该表没有"创建表"迁移,因此"删除表"迁移无权存在.如果您确实不想删除迁移,可以使用原始SQL重写它:

def up
  connection.execute 'drop table if exists campaigns'
end
Run Code Online (Sandbox Code Playgroud)

if exists完全符合您的想法:它只会尝试丢弃表,如果它在那里.

关于这个东西:

我认为你不应该删除迁移,以便将来在该项目上工作的任何人都可以运行它们并拥有准确的数据库.

迁移旨在将应用程序的现有实例从状态A获取到状态-B.如果您正在启动一个新实例,那么您将使用schema.rb(或structure.sql)初始化应用程序,并且不需要迁移.此外,一旦迁移已应用于应用程序的每个实例,除非您想尝试向后移动,否则不再需要迁移.我倾向于在发布后的几周内清除旧的迁移,以防止混乱.