如何使用 Rails 迁移删除列

Posted

技术标签:

【中文标题】如何使用 Rails 迁移删除列【英文标题】:How to drop columns using Rails migration 【发布时间】:2011-02-19 08:06:49 【问题描述】:

通过 Rails 迁移删除数据库表列的语法是什么?

【问题讨论】:

【参考方案1】:
remove_column :table_name, :column_name

例如:

remove_column :users, :hobby

将从 users 表中删除 hobby 列。

【讨论】:

@XåpplI'-I0llwlg'I-感谢您的评论。 change 方法可用于在 Rails 4 应用程序中删除列,但不应在 Rails 3 中使用。我相应地更新了答案。 您也可以在change 方法中使用remove_column :table_name, :column_name, :type, :options,因为如果您指定类型,则可以恢复迁移。来自文档:typeoptions 参数如果存在将被忽略。在迁移的change 方法中提供这些可能会有所帮助,以便可以将其还原。在这种情况下,typeoptions 将被 add_column 使用。 在 Rails4 中,您可以在 change 方法中删除列,但前提是您指定了列类型。例如。 remove_column, :table_name, :column_name, :column_type。否则在尝试运行迁移时会出现以下错误:remove_column is only reversible if given a type 在主要答案中可能值得注意的是removing a column does not remove the corresponding index if it exists【参考方案2】:

对于旧版本的 Rails

ruby script/generate migration RemoveFieldNameFromTableName field_name:datatype

适用于 Rails 3 及更高版本

rails generate migration RemoveFieldNameFromTableName field_name:datatype

【讨论】:

“rails g”可以作为“rails generate”的替代品 rails g migration remove_field_name_from_table_name field_name:datatype 也可以 另请注意,AddXXXtoTTTRemoveXXXFromTTT 后面可能跟有一个由空格分隔的filed_name:data_type 列表,并且将创建相应的add_column 和remove_column 语句:rails g migration RemoveUnusefulFieldsFromUsers hair_color:string favorite_number:integer 删除两个属性使用一次迁移。另请注意,change 方法不支持remove_column,因此您必须同时编写updown Rails 4 似乎为此支持 change。回滚工作正常。 @AdamGrant 我认为如果您使用可以reverted*change 方法,您需要告知数据类型(以及所有其他字段修饰符) ,因此如果您回滚该迁移,则可以正确重新创建该字段。 * 当我说reverted时,那是在数据库结构方面,当然,该列的数据显然会丢失。【参考方案3】:

Rails 4 已经更新,因此可以在迁移中使用 change 方法删除列,迁移将成功回滚。请阅读 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

确保在从数据库表中删除列时不要使用 change 方法(Rails 3 应用程序的迁移文件中不需要的示例):

  def change
    remove_column :table_name, :field_name
  end

Rails 3 中的 change 方法在 remove_column 方面并不聪明,因此您将无法回滚此迁移。

【讨论】:

然后运行 ​​rake db:migrate @Powers - 出色而明确的答案 - 您能否详细说明以下内容:“Rails 3 中的更改方法在 remove_column 方面并不聪明,因此您将无法回滚这次迁移。” @BKSpureon - 在 Rails 3 中,如果您使用 change 方法,则 rake db:rollback 命令将出错。 rake db:rollbackrake db:migrate 基本相反。此错误已在 Rails 4 中修复 :) 在 Rails 4 中,我尝试回滚更改删除列。它失败并声明您必须指定 data_type (如您的答案中的向下代码) 我遇到了与@rmcshry 相同的问题。我的 rails 版本是 4.2.2,我使用了 change 方法。当我尝试回滚时,发生错误,remove_column 只有在给定类型时才可逆。【参考方案4】:

在 rails4 应用程序中,也可以使用 change 方法来删​​除列。第三个参数是 data_type 并且在可选的第四个中您可以提供选项。它有点隐藏在the documentation 上的“可用转换”部分中。

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

【参考方案6】:

Rails 5 和 6 的清晰简单说明

警告:如果您从数据库中删除列,您将丢失数据。要继续,请参见下文: 警告:以下说明适用于简单的迁移。对于复杂的迁移,例如数百万行,您必须考虑失败的可能性,您还必须考虑如何优化迁移以使其快速运行,以及用户在迁移过程中使用您的应用程序的可能性.如果您有多个数据库,或者如果任何事情都非常复杂,那么如果出现问题,请不要怪我!

1。创建迁移

在终端中运行以下命令:

rails generate migration remove_fieldname_from_tablename fieldname:fieldtype

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

示例:

就我而言,我想从quotes 表中删除accepted 列(布尔值):

rails g migration RemoveAcceptedFromQuotes accepted:boolean

See the documentation 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:migraterails db:migrate(两者相同)

....然后你就去参加比赛了!

【讨论】:

现在迁移也可以作为rails db:migrate运行【参考方案7】:

生成迁移以删除列,如果迁移 (rake db:migrate),它应该删除列。如果此迁移被回滚 (rake db:rollback),它应该添加列

语法:

remove_column :table_name, :column_name, :type

删除列,如果迁移被回滚,也添加列

例子:

remove_column :users, :last_name, :string

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

【讨论】:

【参考方案8】:

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

rails generate migration remove_COLUMNNAME_from_TABLENAME COLUMNNAME:DATATYPE

例如从表 users 中删除列 access_level(string):

rails generate migration remove_access_level_from_users access_level:string

然后运行:

rake db:migrate

【讨论】:

【参考方案9】:

删除 RAILS 5 应用程序的列

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

上面的命令在db/migrate 目录中生成一个迁移文件。 Snippet blow 是 Rails 生成器生成的表示例中的删除列之一,

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

我还为 Rails 制作了一份快速参考指南,可以在 here 找到。

【讨论】:

【参考方案10】:

您可以尝试以下方法:

remove_column :table_name, :column_name

(Official documentation)

【讨论】:

【参考方案11】:
rails g migration RemoveXColumnFromY column_name:data_type

X = 列名 Y = 表名

编辑

根据 cmets 将 RemoveXColumnToY 更改为 RemoveXColumnFromY - 更清楚地了解迁移的实际操作。

【讨论】:

"Remove column to table" 听起来很奇怪,所以 from 似乎是这里更好的选择。 @SebastianvomMeer 是的,我同意 - 使用 'from' 的英文读起来更好【参考方案12】:

要从表中删除列,您必须运行以下迁移:

rails g migration remove_column_name_from_table_name column_name:data_type

然后运行命令:

rake db:migrate

【讨论】:

【参考方案13】:

给出下面的命令,它会自行添加到迁移文件中

rails g migration RemoveColumnFromModel

运行上述命令后,您可以检查迁移文件 remove_column 代码必须自行添加在那里

然后迁移数据库

rake db:migrate

【讨论】:

【参考方案14】:

remove_column 中的change 方法将帮助您从表中删除列。

class RemoveColumn < ActiveRecord::Migration
  def change
    remove_column :table_name, :column_name, :data_type
  end
end

转到此链接以获取完整参考:http://guides.rubyonrails.org/active_record_migrations.html

【讨论】:

【参考方案15】:

只需简单的 3 个步骤即可从表中删除列:

    写这个命令

rails g migration remove_column_from_table_name

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

然后转到这个文件。

    你必须写的内部文件

    remove_column :table_name, :column_name

    最后去控制台然后做

    rake db:migrate

【讨论】:

【参考方案16】:

还有一个来自 rails 控制台

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

【讨论】:

【参考方案17】:

很简单,你可以删除列

remove_column :table_name, :column_name

例如,

remove_column :posts, :comment

【讨论】:

【参考方案18】:

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

rails g migration RemoveAgeFromUsers age:string

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

rails db:migrate

【讨论】:

【参考方案19】:

通过remove_column :table_name, :column_name 在迁移文件中

您可以通过键入以下内容直接在 Rails 控制台中删除列:ActiveRecord::Base.remove_column :table_name, :column_name

【讨论】:

【参考方案20】:

这样做;

rails g migration RemoveColumnNameFromTables column_name:type

rails g migration RemoveTitleFromPosts title:string

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

参考:Strong migration

【讨论】:

【参考方案21】:
    在模型中将该列标记为已忽略
class MyModel < ApplicationRecord
  self.ignored_columns = ["my_field"]
end
    生成迁移
$ bin/rails g migration DropMyFieldFromMyModel
    编辑迁移
class DropMyFieldFromMyModel < ActiveRecord::Migration[6.1]
  def change
    safety_assured  remove_column :my_table, :my_field 
  end
end
    运行迁移
$ bin/rails db:migrate

【讨论】:

【参考方案22】:

第 1 步:创建迁移

  rails g migration remove_column_name_from_table

第 2 步:在刚刚创建的文件迁移中更改代码

导轨版本

  def change
    remove_column :table_name, :column_name, :datatype
  end

rails 版本 >= 3

  def change
    remove_column :table_name, :column_name
  end

第 3 步:迁移

rake db:migrate

【讨论】:

简单明了【参考方案23】:

只需在 Rails 控制台中运行它

ActiveRecord::Base.connection.remove_column("table_name", :column_name, :its_data_type)

TableName.find_by_sql(“ALTER TABLE table_name DROP column_name”)

【讨论】:

我来自未来,这是与您的数据库交互的糟糕方式。

以上是关于如何使用 Rails 迁移删除列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 迁移中将列(包含内容)移动到另一个表?

Rails迁移:从表中删除列

Rails DB 迁移 - 如何删除表?

Rails 5:为啥即使我删除了迁移文件,rails 也会向 schema.rb 添加列

如何在 Ruby on Rails 迁移中使列唯一并为其编制索引?

Rails 5 - 如何添加UUID列