我在本地环境中的 postgres 数据库中创建了一个“campaigns”表。 我从未提交过更改,因此从未将其推送到 heroku 上的生产中。

当我改变了需要那个表的想法时,我愚蠢地手动删除了迁移(我现在知道永远不要这样做)。 但是,由于迁移已经运行,我创建了一个21041211003219_drop_campaigns_table迁移来从本地数据库中删除表。

现在,当我在生产中运行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'             

我知道它正在尝试为一个它从来不知道存在的表运行删除表迁移,但我不确定如何处理这个问题。

我尝试删除删除表迁移,推送到生产并运行它,但它仍然尝试运行该迁移。

回滚该提交后,我一直在考虑在重新创建表的21041211003219_drop_campaigns_table迁移之前手动创建带有21041211003219_drop_campaigns_table的新迁移,但随后我觉得我将保留本地 postgres 数据库中存在的表(因为21041211003219_drop_campaigns_table已经在本地运行)。

我是否继续手动创建,然后尝试重新运行删除迁移?

有人可以就这里的最佳行动方案向我提出建议吗?

#1楼 票数:41

您可以通过将if_exists: true添加到drop_table来关闭错误PG::UndefinedTable: ERROR: table "campaigns" does not exist删除已经不存在的表时:

def up
  drop_table(:campaigns, if_exists: true)
end

这个选项的文档很少,但自 2015 年初以来就存在于 Rails 中,我认为它比手动编写 SQL 更干净,因为它还处理与各种数据库适配器的兼容性。

#2楼 票数:14 已采纳

只需删除有问题的迁移,然后继续做更​​有趣的事情。 显然,该表没有“创建表”迁移,因此“删除表”迁移无权存在。 如果你真的不想删除迁移,你可以使用原始 SQL 重写它:

def up
  connection.execute 'drop table if exists campaigns'
end

if exists完全符合您的想法:它仅在表存在时才尝试删除该表。

关于这个东西:

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

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

#3楼 票数:3

if_exists不适用于 rails 4.2 和 PG 9.6。 感谢@MartinSommer 提到table_exists? . 对于后代,这是我使用的语法,读起来更清晰。

drop_table :campaigns if table_exists?(:campaigns)

#4楼 票数:1

当您删除迁移文件并希望删除相应的表时,例如student_items ,有两种方法:

  1. 简单的方法:将迁移文件恢复归档并运行

    rails db:rollback
  2. 创建迁移:

     rails g migration DropStudentItemTable

    并在迁移文件中添加此代码:

     class DropStudentItemTables < ActiveRecord::Migration[6.0] def down table_exists?(:student_items) ? drop_table(:student_items) : nil end end

#5楼 票数:0

普通 SQL

  def down
    execute <<~SQL
      DROP TABLE IF EXISTS campaigns;
    SQL
  end

  ask by macoughl translate from so

未解决问题?本站智能推荐:

5回复

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

我在本地环境中的 postgres 数据库中创建了一个“campaigns”表。 我从未提交过更改,因此从未将其推送到 heroku 上的生产中。 当我改变了需要那个表的想法时,我愚蠢地手动删除了迁移(我现在知道永远不要这样做)。 但是,由于迁移已经运行,我创建了一个21041211003219_
1回复

psql未定义表,关系不存在

每次我尝试打开红宝石终端菜单进行测试时,都会出现此问题吗? 我正在活动记录中。 每当我尝试使用一种将事件添加到数据库的方法时,都会收到此错误。 这是我的模式-
1回复

Rails:查询联接表的子项是否存在

设定: 题: 编辑:澄清问题。 我希望给定用户不返回所有项目。 提示:项目可以有可能的销售范围限定为用户:如果一个项目有两个销售,一个返回,一个不是,我不想显示该项目。 这是行不通的,因为它会查询所有return_sales的商品,而不仅仅是针对用户范围的商品。
3回复

如何定义在 Ruby on Rails 5.2 中的 ActiveRecord 迁移中创建表时要使用的序列?

我需要为我的表的 ID 字段分配一个特定的 Postgres 序列。 在模型中,我尝试定义以下对 Posgres 没有影响的设置: class MyObject < ActiveRecord::Base self.sequence_name = "global_seq" 通常
1回复

如何从ActiveRecord的序列化数组迁移到Postgres Array数据类型

Rails 4支持postgres的数组数据类型 ,而我们想开始利用postgres中的数组类型,如何将现有的ActiveRecord序列化数组字段迁移到新数据类型?
2回复

Rails-使用PostgresSQL在数据库迁移中指定固定长度的列

似乎在列修饰符中只有:limit ,它指定此列的最大长度。 但是,如果我想指定长度正确怎么办? 例如,手机号码必须包含11位数字,因此我不希望用户输入无效的号码。 当然,我也可以在模型逻辑甚至前端进行验证,但是在数据库级别添加约束似乎更安全。 有没有办法在Rails中实现这一目标? 还
2回复

使用 ActiveRecord 查询记录列表,其中每个项目的外键都存在于散列中

我有四种模型 - 用户、代理、列表和查询。 用户has_one代理、代理has_many Listings 和 Listing has_many 。 我有一个查询,我在哪里得到:user_id ,所以我可以得到它的 Agency 和 Listings 的集合。 我需要属于某个列表的查询。 我
1回复

Rails Activerecord 将列添加到多个表

我需要进行迁移,其中将一列添加到三个单独的表中。 视图列是一个整数,还需要默认 => 0。如何使用 activerecord 命令添加这些列? 我正在使用 postgreSQL 数据库。 我的迁移应该如下所示:
1回复

ActiveRecord在Heroku上错误地加载二进制字段,在OSX上很好

我有一个rails 3.1应用程序,它将图像存储在postgresql数据库的二进制字段中(我知道在数据库中存储图像的潜在问题,但现在必须这样做)。 在开发模式和OSX上的规格本地一切都很好,但所有图像都在部署到Heroku的应用程序中被破坏。 我已经通过将本地计算机指向heroku实例使用
1回复

根据关联表中的条件从表中获取记录

我有两个模型School和Expense ,其中school有很多费用, Expense有一个名为cost的属性 我正在尝试仅获取其费用成本大于某个值(例如1000)的那些学校,我尝试了此查询 此查询的问题是,如果一所学校有多个费用大于1000的费用,则它返回的重复值是我所希望的,