我错误地将列命名为 hased_password
而不是 hashed_password
。
如何更新数据库架构,使用迁移重命名此列?
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 使用:
虽然 up
和 down
方法仍然适用,但 Rails 3.1 接收了一个 change
方法,该方法“知道如何迁移数据库并在迁移回滚时将其反转,而无需编写单独的 down 方法”。
有关详细信息,请参阅“Active Record Migrations”。
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
方法,而不是上面部分中提到的 up
和 down
。生成的 change
方法是:
$ > rails g migration ChangeColumnName
这将创建一个类似于以下内容的迁移文件:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
在我看来,在这种情况下,最好使用 rake db:rollback
,然后编辑您的迁移并再次运行 rake db:migrate
。
但是,如果您不想丢失列中的数据,请使用 rename_column
。
如果该列已经填充了数据并已投入生产,我建议采用逐步的方法,以避免在等待迁移时生产停机。
首先,我将创建一个数据库迁移以添加具有新名称的列,并使用旧列名称中的值填充它们。
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
。
我意识到这涉及到一个过程,但我宁愿这样做,也不愿在生产迁移方面遇到问题。
execute "Update table_name set correct_name_column_one = old_name_column_one"
请参阅“Active Record Migrations”文档中的“可用转换”部分。
rename_column(table_name, column_name, new_column_name):
重命名列但保留类型和内容。
运行此命令以创建迁移文件:
rails g migration ChangeHasedPasswordToHashedPassword
然后在 db/migrate
文件夹中生成的文件中,写入 rename_column
,如下所示:
class ChangeOldColumnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
从 API:
rename_column(table_name, column_name, new_column_name)
这会重命名列,但类型和内容保持不变。
如果您的代码未与其他人共享,那么最好的选择是仅执行 rake db:rollback
,然后在迁移和 rake db:migrate
中编辑您的列名。而已
您可以编写另一个迁移来重命名该列
def change
rename_column :table_name, :old_name, :new_name
end
而已。
rake db:rollback
是一个很好的建议。但是就像你说的那样,只有在迁移还没有被推送的情况下。
某些版本的 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 - Migrations 或 Active Record Migrations。
在使用 PostgreSQL 数据库处理 Rails 6 应用程序时,我遇到了这个挑战。
这是我修复它的方法:
在我的例子中,table_name
是“Products”,old_column
是“SKU”,new_column
是“ProductNumber”。
创建一个包含重命名列的命令的迁移文件: rails generate migration RenameSKUToProductNumberInProducts 打开 db/migrate 目录中的迁移文件: db/migrate/20201028082344_rename_sku_to_product_number_in_products.rb 添加重命名列的命令: class RenameSkuToProductNumberInProducts < ActiveRecord:: Migration[6.0] def change # rename_column :table_name, :old_column, :new_column rename_column :products, :sku, :product_number end end 保存,然后运行迁移命令: rails db:migrate
您现在可以通过查看模式文件来确认列的重命名:
db/schema.rb
如果您对列的重命名不满意,您可以随时回滚:
rails db:rollback
注意:努力在所有调用它的地方将列名修改为新名称。
作为替代选择,如果您不接受迁移的想法,那么 ActiveRecord 有一个引人注目的宝石,它将自动为您处理名称更改,Datamapper 样式。您所要做的就是更改模型中的列名,并确保将 Model.auto_upgrade!
放在 model.rb 的底部,然后中提琴!数据库即时更新。
请参阅https://github.com/DAddYE/mini_record
注意:您需要核对 db/schema.rb
以防止冲突。
它仍处于测试阶段,显然不适合所有人,但它仍然是一个令人信服的选择。我目前在两个非平凡的生产应用程序中使用它,没有任何问题。
对于 Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
table_name
是复数。例如:学生
如果您需要切换列名,则需要创建一个占位符以避免“列名重复”错误。这是一个例子:
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
如果当前数据对您来说不重要,您可以使用以下方法取消原始迁移:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
没有引号,然后在原始迁移中进行更改并通过以下方式再次运行向上迁移:
rake db:migrate
只需创建一个新的迁移,然后在一个块中使用 rename_column
,如下所示。
rename_column :your_table_name, :hased_password, :hashed_password
生成迁移文件:
rails g migration FixName
创建 db/migrate/xxxxxxxxxx.rb
。
根据您的意愿编辑迁移:
class FixName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
手动我们可以使用以下方法:
我们可以手动编辑迁移,例如:
打开 app/db/migrate/xxxxxxxxx_migration_file.rb
将 hased_password 更新为 hashed_password
运行以下命令 $> rake db:migrate:down VERSION=xxxxxxxxx
然后它将删除您的迁移:
$> rake db:migrate:up VERSION=xxxxxxxxx
它将使用更新的更改添加您的迁移。
运行 rails g migration ChangesNameInUsers
(或您想命名的任何名称)
打开刚刚生成的迁移文件,在方法中添加这一行(在 def change
和 end
之间):
rename_column :table_name, :the_name_you_want_to_change, :the_new_name
保存文件,然后在控制台中运行 rake db:migrate
检查您的 schema.db
以查看数据库中的名称是否已实际更改!
希望这可以帮助 :)
def change
rename_column :table_name, :old_column_name, :new_column_name
end
让我们KISS。只需要三个简单的步骤。以下适用于 Rails 5.2。
1.创建迁移
rails g 迁移 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
你要去参加比赛了!
生成 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
$: 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
在控制台中:
rails generate migration newMigration
在新迁移文件中:
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
打开 Ruby on Rails 控制台并输入:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
你有两种方法可以做到这一点:
在这种类型中,它会在回滚时自动运行它的反向代码。 def change rename_column :table_name, :old_column_name, :new_column_name end 对于这种类型,rake db:migrate 时运行 up 方法,rake db:rollback 时运行 down 方法: 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
我在 Rails 5.2 上,并试图重命名设计用户上的列。
rename_column
位对我有用,但单数 :table_name
抛出“未找到用户表”错误。复数为我工作。
rails g RenameAgentinUser
然后将迁移文件更改为:
rename_column :users, :agent?, :agent
哪里:代理?是旧的列名。
您可以编写迁移运行以下命令来更新列名:
rename_column :your_table_name, :hased_password, :hashed_password
此外,请确保使用新列名更新代码中旧列名的任何用法。
create_table
的近亲是 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
rails g migration migrationName
因此,您转到生成的迁移并添加:
rename_column :table, :old_column, :new_column
对方法
首先你需要运行
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
只需使用以下命令生成迁移:
rails g migration rename_hased_password
之后编辑迁移并在 change
方法中添加以下行:
rename_column :table, :hased_password, :hashed_password
这应该可以解决问题。
self.up
中所做的操作是正常做法,但我不会说self.down
“应该总是相反”。取决于您的迁移环境。仅仅把“对立面”放在“对面”可能不是“正确”的向下迁移。def self.up
和def self.down
替换为def change
,它会知道如何回滚。change
方法不是完全证明,因此倾向于使用up
和down
方法进行复杂迁移。