1541

我错误地命名了一个列hased_password而不是hashed_password.

如何更新数据库架构,使用迁移重命名此列?

4

31 回答 31

2436
rename_column :table, :old_column, :new_column

您可能需要创建一个单独的迁移来执行此操作。(FixColumnName根据需要重命名。):

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

然后编辑迁移以执行您的意愿:

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

对于 Rails 3.1 使用:

虽然updown方法仍然适用,但 Rails 3.1 接收了一个change“知道如何迁移数据库并在迁移回滚时反转它,而无需编写单独的 down 方法”的方法。

有关详细信息,请参阅“ Active Record 迁移”。

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

如果您碰巧有一大堆要重命名的列,或者需要一遍又一遍地重复表名:

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

你可以change_table用来让事情变得更整洁:

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

然后db:migrate像往常一样,或者不管你怎么做你的生意。


对于 Rails 4:

在创建Migration用于重命名列的方法时,Rails 4 会生成一个change方法,而不是上面部分中提到的upand 。down生成的change方法是:

$ > rails g migration ChangeColumnName

这将创建一个类似于以下内容的迁移文件:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
于 2010-01-02T16:31:20.810 回答
71

在我看来,在这种情况下,最好使用rake db:rollback,然后编辑您的迁移并再次运行rake db:migrate.

但是,如果您不想丢失列中的数据,请使用rename_column.

于 2010-01-03T00:55:51.610 回答
36

如果该列已经填充了数据并已投入生产,我建议采用逐步的方法,以避免在等待迁移时生产停机。

首先,我将创建一个数据库迁移以添加具有新名称的列,并使用旧列名称中的值填充它们。

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

然后我会提交该更改,并将更改推送到生产中。

git commit -m 'adding columns with correct name'

然后,一旦提交被推送到生产中,我就会运行。

Production $ bundle exec rake db:migrate

然后我会将所有引用旧列名的视图/控制器更新为新列名。运行我的测试套件,并提交这些更改。(在确保它在本地工作并首先通过所有测试之后!)

git commit -m 'using correct column name instead of old stinky bad column name'

然后我会将该承诺投入生产。

此时,您可以删除原始列,而不必担心与迁移本身相关的任何停机时间。

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

然后将最新的迁移推送到生产环境并bundle exec rake db:migrate在后台运行。

我意识到这涉及到一个过程,但我宁愿这样做,也不愿在生产迁移方面遇到问题。

于 2013-08-30T22:08:14.303 回答
27

请参阅“ Active Record 迁移”文档中的“可用转换”部分。

rename_column(table_name, column_name, new_column_name):

重命名列但保留类型和内容。

于 2010-01-02T16:26:03.413 回答
20

运行此命令以创建迁移文件:

rails g migration ChangeHasedPasswordToHashedPassword

然后在文件db/migrate夹中生成的文件中,写rename_column如下:

class ChangeOldColumnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end
于 2014-12-03T11:45:43.390 回答
16

从 API:

rename_column(table_name, column_name, new_column_name)

这会重命名列,但类型和内容保持不变。

于 2011-02-18T11:15:59.200 回答
12

如果您的代码未与其他人共享,那么最好的选择是rake db:rollback 在迁移和rake db:migrate. 就是这样

您可以编写另一个迁移来重命名该列

 def change
    rename_column :table_name, :old_name, :new_name
  end

就是这样。

于 2013-12-04T14:34:30.590 回答
12

某些版本的 Ruby on Rails 支持迁移的up/down方法,如果你的迁移中有up/down方法,那么:

def up
    rename_column :table_name, :column_old_name, :column_new_name
end

def down
    rename_column :table_name, :column_new_name, :column_old_name
end

如果您change在迁移中有该方法,则:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

有关更多信息,请参阅:Ruby on Rails - 迁移Active Record 迁移

于 2014-02-14T10:38:18.910 回答
9

作为替代选择,如果您不接受迁移的想法,ActiveRecord 有一个引人注目的宝石,它将自动为您处理名称更改,Datamapper 样式。您所做的只是更改模型中的列名,并确保将其放在Model.auto_upgrade!model.rb 和 viola 的底部!数据库即时更新。

https://github.com/DAddYE/mini_record

注意:您需要使用核武器db/schema.rb来防止冲突。

它仍处于测试阶段,显然不适合所有人,但它仍然是一个令人信服的选择。我目前在两个非平凡的生产应用程序中使用它,没有任何问题。

于 2012-01-30T20:00:58.940 回答
9

在使用 PostgreSQL 数据库处理 Rails 6 应用程序时,我遇到了这个挑战。

这是我修复它的方法:

在我的情况下,table_name是“产品”,old_column是“SKU”,new_column是“ProductNumber”。

  1. 创建一个包含用于重命名列的命令的迁移文件:

     rails generate migration RenameSKUToProductNumberInProducts
    
  2. 在以下位置打开迁移文件db/migrate directory

     db/migrate/20201028082344_rename_sku_to_product_number_in_products.rb
    
  3. 添加用于重命名列的命令:

     class RenameSkuToProductNumberInProducts < ActiveRecord::Migration[6.0]
       def change
         # rename_column :table_name, :old_column, :new_column
         rename_column :products, :sku, :product_number
       end
     end
    
  4. 保存,然后运行迁移命令:

     rails db:migrate
    

您现在可以通过查看模式文件来确认列的重命名:

    db/schema.rb

如果您对列的重命名不满意,您可以随时回滚:

    rails db:rollback

注意:努力在所有调用它的地方将列名修改为新名称。

于 2020-10-28T08:34:01.680 回答
8

如果您需要切换列名,则需要创建一个占位符以避免“列名重复”错误。这是一个例子:

class SwitchColumns < ActiveRecord::Migration
  def change
    rename_column :column_name, :x, :holder
    rename_column :column_name, :y, :x
    rename_column :column_name, :holder, :y
  end
end
于 2013-09-09T21:10:38.723 回答
8

对于 Ruby on Rails 4:

def change
    rename_column :table_name, :column_name_old, :column_name_new
end
于 2015-01-20T14:44:05.113 回答
7

如果当前数据对您来说不重要,您可以使用以下方法取消原始迁移:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

没有引号,然后在原始迁移中进行更改并通过以下方式再次运行向上迁移:

rake db:migrate
于 2013-07-26T09:11:47.923 回答
7

只需创建一个新的迁移,并在一个块中,使用rename_column如下。

rename_column :your_table_name, :hased_password, :hashed_password
于 2014-03-24T15:05:51.777 回答
6

生成迁移文件:

rails g migration FixName

这会创建db/migrate/xxxxxxxxxx.rb.

根据您的意愿编辑迁移:

class FixName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
于 2015-12-28T13:24:46.800 回答
5

手动我们可以使用以下方法:

我们可以手动编辑迁移,例如:

  • 打开app/db/migrate/xxxxxxxxx_migration_file.rb

  • 更新hased_passwordhashed_password

  • 运行以下命令

    $> rake db:migrate:down VERSION=xxxxxxxxx
    

然后它将删除您的迁移:

$> rake db:migrate:up VERSION=xxxxxxxxx

它将使用更新的更改添加您的迁移。

于 2014-07-14T13:58:02.407 回答
5

运行rails g migration ChangesNameInUsers(或任何您想命名的名称)

打开刚刚生成的迁移文件,在方法中加入这一行(和之间def changeend

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

保存文件,rake db:migrate在控制台运行

检查您schema.db的名称以查看数据库中的名称是否已实际更改!

希望这可以帮助 :)

于 2016-12-23T16:10:36.473 回答
5
 def change
    rename_column :table_name, :old_column_name, :new_column_name
  end
于 2017-06-08T18:01:21.970 回答
5

让我们亲吻吧。只需要三个简单的步骤。以下适用于Rails 5.2

1. 创建迁移

  • rails g migration RenameNameToFullNameInStudents

  • rails g RenameOldFieldToNewFieldInTableName- 这样以后代码库的维护人员就很清楚了。(使用复数作为表名)。

2. 编辑迁移

# I prefer to explicitly write the上下and_methods.

# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb

class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
  def up
    # rename_column :table_name, :old_column, :new_column
    rename_column :students, :name, :full_name
  end

  def down
            # Note that the columns are reversed
    rename_column :students, :full_name, :name
  end
end

3. 运行你的迁移

rake db:migrate

你要去参加比赛了!

于 2019-01-14T05:06:38.920 回答
4

生成 Ruby on Rails 迁移

$:> rails g migration Fixcolumnname

在迁移文件 (XXXXfixcolumnname.rb) 中插入代码

class Fixcolumnname < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
于 2016-01-26T12:26:29.320 回答
4
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

打开该迁移文件并按如下方式修改该文件(请输入您的原始文件table_name

class  RenameHashedPasswordColumn < ActiveRecord::Migration
  def change
    rename_column :table_name, :hased_password, :hashed_password
  end
end
于 2016-03-23T05:49:28.533 回答
2

你有两种方法可以做到这一点:

  1. 在这种类型中,它会在回滚时自动运行它的反向代码。

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
  2. 对于这种类型,它运行 up 方法 whenrake db:migrate并运行 down 方法 when rake db:rollback

    def self.up
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
    def self.down
      rename_column :table_name,:new_column_name,:old_column_name
    end
    
于 2015-01-29T10:47:43.170 回答
2

打开 Ruby on Rails 控制台并输入:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
于 2015-06-03T07:46:52.443 回答
2

我在 Rails 5.2 上,并试图重命名设计用户上的列。

rename_column位对我有用,但单数:table_name引发了“未找到用户表”错误。复数为我工作。

rails g RenameAgentinUser

然后将迁移文件更改为:

rename_column :users, :agent?, :agent

哪里:代理?是旧的列名。

于 2018-09-06T13:42:53.350 回答
2

您可以编写迁移运行以下命令来更新列名:

rename_column :your_table_name, :hased_password, :hashed_password

此外,请确保使用新列名更新代码中旧列名的任何用法。

于 2021-04-22T18:05:10.453 回答
2

在控制台中:

rails generate migration newMigration

在新迁移文件中:

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end
于 2021-12-24T01:01:21.127 回答
1

create_tableis的近亲change_table,用于更改现有表。它以类似的方式使用,create_table但让给块的对象知道更多技巧。例如:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

如果我们将它与其他更改方法一起使用,例如:删除/添加索引/删除索引/添加列,这种方式会更有效。我们可以这样做:

改名

t.rename :old_column_name, :new_column_name

添加列

t.string :new_column

删除列

t.remove :removing_column

索引栏

t.index :indexing_column
于 2016-05-21T05:32:00.123 回答
0

只需使用以下命令生成迁移:

rails g migration rename_hased_password

之后编辑迁移并在change方法中添加以下行:

rename_column :table, :hased_password, :hashed_password

这应该可以解决问题。

于 2017-10-05T12:02:57.950 回答
0

rails g migration migrationName

因此,您转到生成的迁移并添加:

rename_column :table, :old_column, :new_column

对方法

于 2021-06-15T19:25:23.563 回答
0

首先你需要运行

rails g migration create_new_column_in_tablename new_column:datatype
rails g migration remove_column_in_tablename old_column:datatype

然后您需要检查 db/migration 您可以检查 nem 迁移中的详细信息,如果所有详细信息都正确,则需要运行:

rails db:migrate
于 2021-09-04T04:34:04.947 回答
-1

Rails 5 迁移更改

例如:

rails g model 学生 student_name:string age:integer

如果您想将student_name列更改为名称

注意:- 如果你不运行rails db:migrate

您可以执行以下步骤

rails d model 学生 student_name:string age:integer

这将删除生成的迁移文件,现在您可以更正列名

rails g model 学生姓名:字符串 年龄:整数

如果您已迁移(rails db:migrate),请使用以下选项更改列名

rails g 迁移 RemoveStudentNameFromStudent student_name:string

rails g 迁移 AddNameToStudent 姓名:字符串

于 2017-12-20T12:08:30.580 回答