如何使用Rails迁移删除列


Answers:


917
remove_column :table_name, :column_name

例如:

remove_column :users, :hobby

将从用户表中删除爱好列。


9
并确保在内部updown方法(而不是)中执行此操作change,如@Powers的答案中所述。
XåpplI'-I0llwlg'I -

7
@XåpplI'-I0llwlg'I,谢谢您的评论。更改方法可用于在Rails 4应用程序中删除列,但不应在Rails 3中使用。我相应地更新了答案。
鲍尔斯

9
您也可以remove_column :table_name, :column_name, :type, :optionschange方法中使用,因为如果指定类型,则可以恢复迁移。从文档:typeoptions参数将如果存在被忽略。在迁移change方法中提供这些内容可能会有所帮助,以便可以还原它。在这种情况下,type并且options将add_column使用。
Nicolas 2014年

24
在Rails4中,可以删除change方法中的列,但前提是您指定了列类型。例如remove_column, :table_name, :column_name, :column_type。否则,在尝试运行迁移时会出现以下错误:remove_column is only reversible if given a type
Dennis 2014年

5
在主要答案中可能值得注意的是,删除列不会删除相应的索引(如果存在的话)
sameers

371

对于旧版本的Rails

ruby script/generate migration RemoveFieldNameFromTableName field_name:datatype

适用于Rails 3及更高版本

rails generate migration RemoveFieldNameFromTableName field_name:datatype

18
“ rails g”可以用作“ rails generate”的替代方法
Noz 2012年

44
rails g migration remove_field_name_from_table_name field_name:datatype也有效
Stuart Nelson

6
还需要注意的是AddXXXtoTTT一个RemoveXXXFromTTT可以跟随filed_name的白名单间隔:DATA_TYPE,并且将创建的适当add_column和remove_column语句:rails g migration RemoveUnusefulFieldsFromUsers hair_color:string favorite_number:integer除去使用单个迁移两个属性。另请注意,remove_column方法不支持change,因此您必须同时编写updown
Claudio Floreani

3
Rails 4似乎change对此提供了支持。回滚按应有的方式进行。
Unknown_Guy 2013年

2
@AdamGrant我认为,如果您使用的是可恢复的change方法*,则需要告知数据类型(以及所有其他字段修饰符),因此,如果回滚该迁移,则可以正确地重新创建该字段。*当我说还原时,这是在数据库结构方面,当然,该列中的数据显然会丢失。
RFVoltolini

117

Rails 4已更新,因此可以在迁移中使用更改方法删除列,并且迁移将成功回滚。请阅读有关Rails 3应用程序的以下警告:

Rails 3警告

请注意,使用此命令时:

rails generate migration RemoveFieldNameFromTableName field_name:datatype

生成的迁移将如下所示:

  def up
    remove_column :table_name, :field_name
  end

  def down
    add_column :table_name, :field_name, :datatype
  end

从数据库表中删除列时,请确保不要使用更改方法(例如,Rails 3应用程序的迁移文件中您不想要的示例):

  def change
    remove_column :table_name, :field_name
  end

在谈到remove_column时,Rails 3中的change方法并不明智,因此您将无法回滚此迁移。


3
然后运行rake db:migrate
roxdurazo

1
@Powers-出色而清晰的答案-您能否详细说明以下内容:“在谈到remove_column时,Rails 3中的更改方法并不明智,因此您将无法回滚此迁移。”
BKSpurgeon '16

1
@BKSpurgeon-在Rails 3中,如果使用该change方法,则该rake db:rollback命令将出错。 rake db:rollback与基本上相反rake db:migrate。此错误已在Rails 4中修复:)
Powers

2
在Rails 4中,我尝试回滚一个更改放置列。它失败并指出您必须指定data_type(如您的答案中的向下代码所示)
rmcsharry16年

1
与@rmcsharry一样,我也遇到了同样的问题。我的rails版本是4.2.2,我使用了更改方法。当我尝试回滚时,发生错误,即如果给定类型,remove_column只能是可逆的。
哈比卜

38

在rails4应用程序中,也可以使用change方法删除列。第三个参数是data_type,在可选的第四个参数中可以提供选项。它在文档的 “可用转换”部分中有所隐藏。

class RemoveFieldFromTableName < ActiveRecord::Migration
  def change
    remove_column :table_name, :field_name, :data_type, {}
  end
end

27

有两种很好的方法可以做到这一点:

remove_column

您可以简单地使用remove_column,如下所示:

remove_column :users, :first_name

如果您只需要对架构进行单个更改,那就很好。

change_table块

您也可以使用change_table块执行此操作,如下所示:

change_table :users do |t|
  t.remove :first_name
end

我更喜欢这样做,因为我觉得它更清晰,您可以一次进行一些更改。

以下是受支持的change_table方法的完整列表:

http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table


15

在rails 5中,您可以在终端中使用以下命令:

rails generate migration remove_COLUMNNAME_from_TABLENAME COLUMNNAME:DATATYPE

例如,从表用户中删除列access_level(string):

rails generate migration remove_access_level_from_users access_level:string

然后运行:

rake db:migrate

14

生成迁移以删除列,这样,如果要迁移(rake db:migrate),则应删除column。如果此迁移已回滚(),则应添加列回rake db:rollback

语法:

remove_column:table_name,:column_name,:type

删除列,如果回滚迁移,则还添加列回

例:

remove_column :users, :last_name, :string

注意如果跳过data_type,则迁移将成功删除该列,但是如果回滚迁移,则会引发错误。


13

Rails 5.2的简单明了说明

  • 警告:如果从数据库中删除列,则会丢失数据。要继续,请参见以下内容:
  • 警告:以下说明适用于琐碎的迁移。对于具有数百万行的复杂迁移,您将不得不考虑失败的可能性,还必须考虑如何优化迁移以使其迅速运行,以及用户在使用该应用的同时迁移过程正在发生。如果您有多个数据库,或者任何事情都非常复杂,那么如果出现任何问题,请不要怪我!

1.创建迁移

在终端中运行以下命令:

rails generate migration remove_fieldname_from_tablename fieldname:fieldtype

注意:根据rails约定,表名应为复数形式。

例:

就我而言,我想acceptedquotes表中删除该列(一个布尔值):

rails g migration RemoveAcceptedFromQuotes accepted:boolean

请参阅文档 re:在表中添加/删除字段时的约定:

有一个特殊的语法捷径可以生成将字段添加到表的迁移。

Rails生成迁移add_fieldname_to_tablename fieldname:fieldtype

2.检查迁移

# db/migrate/20190122035000_remove_accepted_from_quotes.rb
class RemoveAcceptedFromQuotes < ActiveRecord::Migration[5.2]
  # with rails 5.2 you don't need to add a separate "up" and "down" method.
  def change
    remove_column :quotes, :accepted, :boolean
  end
end

3.运行迁移

rake db:migrate

....然后您就可以参加比赛了!


现在,迁移也可以运行为rails db:migrate
Imran Ali

12

删除RAILS 5 App的列

rails g migration Remove<Anything>From<TableName> [columnName:type]

上面的命令在db/migrate目录内生成一个迁移文件。片段打击是由Rails生成器从表示例中删除列之一,

class RemoveAgeFromUsers < ActiveRecord::Migration
  def up
    remove_column :users, :age
  end
  def down
    add_column :users, :age, :integer
  end
end

我还制作了一个有关Rails的快速参考指南,可以在这里找到。



10
rails g migration RemoveXColumnFromY column_name:data_type

X =列名
Y =表名

编辑

改变RemoveXColumnToYRemoveXColumnFromY按注释-提供什么样的迁移实际上做的更清晰。


3
“将列删除表”听起来很奇怪,因此这里似乎是更好的选择。
Sebastian vom Meer,

@SebastianvomMeer是的,我同意-英语的“ from”读起来更好
BKSpurgeon

8

要从表中删除该列,您必须在迁移后运行:

rails g migration remove_column_name_from_table_name column_name:data_type

然后运行命令:

rake db:migrate

5

提供以下命令,它将自己添加迁移文件

rails g migration RemoveColumnFromModel

运行上述命令后,您可以检查迁移文件remove_column代码是否必须单独添加

然后迁移数据库

rake db:migrate


5

要通过简单的3个步骤从表中删除列,如下所示:

  1. 写这个命令

rails g migration remove_column_from_table_name

在此名称和时间戳(remove_column from_table_name)创建的终端一号文件中运行此命令后。

然后转到该文件。

  1. 内部文件,你必须写

    remove_column :table_name, :column_name

  2. 最后转到控制台,然后执行

    rake db:migrate


2

来自Rails Console的继承人

ActiveRecord::Migration.remove_column(:table_name, :column_name)


1

通过
remove_column :table_name, :column_name
一个迁移文件

您可以直接在rails控制台中输入以下内容来删除列:
ActiveRecord::Base.remove_column :table_name, :column_name


1

像这样

rails g migration RemoveColumnNameFromTables column_name:type

rails g migration RemoveTitleFromPosts title:string

无论如何,最好还是考虑停机时间,因为ActiveRecord在运行时会缓存数据库列,因此,如果删除列,则可能会导致异常,直到应用程序重新启动为止。

参考:强大的迁移


1

只需删除列

remove_column :table_name, :column_name

例如,

remove_column :posts, :comment

1

首先尝试创建一个运行命令的迁移文件:

rails g migration RemoveAgeFromUsers age:string

然后在项目的根目录上运行运行以下命令的迁移:

rails db:migrate
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.