提问人:user1994764 提问时间:1/3/2010 最后编辑:halferuser1994764 更新时间:12/6/2022 访问量:622134
如何在 Ruby on Rails 迁移中重命名数据库列?
How can I rename a database column in a Ruby on Rails migration?
问:
我错误地命名了一列而不是.hased_password
hashed_password
如何更新数据库架构,使用迁移重命名此列?
答:
请参阅“活动记录迁移”文档中的“可用转换”部分。
rename_column(table_name, column_name, new_column_name):
重命名列,但保留类型和内容。
评论
rename_column
文档。
rename_column :table, :old_column, :new_column
为此,您可能需要创建单独的迁移。(随心所欲地重命名。FixColumnName
bin/rails 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,请使用:
虽然 和 方法仍然适用,但 Rails 3.1 接收到一个方法,该方法“知道如何迁移数据库并在迁移回滚时将其反转,而无需编写单独的 down 方法”。up
down
change
有关详细信息,请参阅“活动记录迁移”。
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:
在创建用于重命名列时,Rails 4 会生成一个方法,而不是上一节中提到的 and。生成的方法为:Migration
change
up
down
change
$ > rails g migration ChangeColumnName
这将创建一个类似于以下内容的迁移文件:
class ChangeColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
评论
self.up
self.down
def self.up
def self.down
def change
change
up
down
在我看来,在这种情况下,最好使用 ,然后编辑您的迁移并再次运行 .rake db:rollback
rake db:migrate
但是,如果列中有不想丢失的数据,请使用 .rename_column
评论
从 API:
rename_column(table_name, column_name, new_column_name)
这将重命名列,但保持类型和内容保持不变。
作为替代选择,如果您不了解迁移的想法,那么 ActiveRecord 有一个引人注目的 gem,它将自动为您处理名称更改,即 Datamapper 样式。您所要做的就是更改模型中的列名,并确保将 model.rb 和 viola 放在底部!数据库会即时更新。Model.auto_upgrade!
查看 https://github.com/DAddYE/mini_record
注意:您需要对 db/schema.rb
进行核弹以防止冲突。
它仍处于测试阶段,显然并不适合所有人,但它仍然是一个令人信服的选择。我目前正在两个重要的生产应用程序中使用它,没有任何问题。
如果当前数据对您来说并不重要,您可以使用以下方法删除原始迁移:
rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'
如果不带引号,则对原始迁移进行更改,并通过以下方式再次运行向上迁移:
rake db:migrate
如果该列已经填充了数据并在生产中生效,我建议采用分步方法,以避免在等待迁移时在生产中停机。
首先,我将创建一个数据库迁移以添加具有新名称的列,并使用旧列名称中的值填充它们。
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"
如果需要切换列名,则需要创建一个占位符以避免出现“重复列名”错误。下面是一个示例:
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: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 - 迁移或 Active Record 迁移。
只需创建一个新的迁移,并在一个块中使用如下。rename_column
rename_column :your_table_name, :hased_password, :hashed_password
手动,我们可以使用以下方法:
我们可以手动编辑迁移,如下所示:
打开
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 ChangeHasedPasswordToHashedPassword
然后在文件夹中生成的文件中,写如下:db/migrate
rename_column
class ChangeOldColumnToNewColumn < ActiveRecord::Migration
def change
rename_column :table_name, :hased_password, :hashed_password
end
end
对于 Ruby on Rails 4:
def change
rename_column :table_name, :column_name_old, :column_name_new
end
评论
table_name
有两种方法可以执行此操作:
在这种类型中,它在回滚时自动运行它的反向代码。
def change rename_column :table_name, :old_column_name, :new_column_name end
对于此类型,它在以下情况下运行 up 方法,并在以下情况下运行 down 方法:
rake db:migrate
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
打开 Ruby on Rails 控制台并输入:
ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column
生成迁移文件:
rails g migration FixName
这创建了 .db/migrate/xxxxxxxxxx.rb
编辑迁移以执行您的意愿:
class FixName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
生成 Ruby on Rails 迁移:
$:> rails g migration Fixcolumnname
在迁移文件 (XXXXXfixcolumnname.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
is 的近亲,用于更改现有表。它的使用方式与块类似,但屈服于块的对象知道更多技巧。例如: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
如果我们将它与 alter 方法一起使用,例如:删除/添加索引/删除索引/添加列,这种方式会更有效。我们可以做这样的事情:
重命名
t.rename :old_column_name, :new_column_name
添加列
t.string :new_column
删除列
t.remove :removing_column
索引列
t.index :indexing_column
评论
运行(或任何你想命名的名称)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
评论
只需使用以下命令生成迁移:
rails g migration rename_hased_password
之后,编辑迁移并在方法中添加以下行:change
rename_column :table, :hased_password, :hashed_password
这应该可以解决问题。
Rails 5 迁移更改
例如:
rails g 模型 学生student_name:字符串 age:integer
如果要将student_name列更改为名称
注意:- 如果你不运行 rails db:migrate
您可以执行以下步骤
rails d 模型 学生student_name:字符串 age:integer
这将删除生成的迁移文件,现在您可以更正您的列名
rails g 模型 学生姓名:字符串 age:integer
如果您迁移了(rails db:migrate),请通过以下选项更改列名
rails g 迁移 RemoveStudentNameFromStudent student_name:string
rails g 迁移 AddNameToStudent name:string
评论
rails g migration RemoveStudentNameFromStudentS student_name:string
我在 rails 5.2 上,并试图重命名 devise User 上的列。
该位对我有用,但单数抛出“找不到用户表”错误。复数对我有用。rename_column
:table_name
rails g RenameAgentinUser
然后将迁移文件更改为:
rename_column :users, :agent?, :agent
哪里:agent?是旧列名。
让我们接吻吧。只需三个简单的步骤。以下是 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
你开始比赛了!
在使用 PostgreSQL 数据库开发 Rails 6 应用程序时,我遇到了这个挑战。
这是我修复它的方法:
在我的情况下,是“产品”,是“SKU”,是“ProductNumber”。table_name
old_column
new_column
创建一个迁移文件,该文件将包含用于重命名列的命令:
rails generate migration RenameSKUToProductNumberInProducts
在以下位置打开迁移文件:
db/migrate directory
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
注意:努力在调用列名的所有位置将列名修改为新名称。
您可以编写迁移,运行以下命令来更新列名:
rename_column :your_table_name, :hased_password, :hashed_password
此外,请确保使用新列名更新代码中旧列名的任何用法。
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 generate migration newMigration
在 newMigration 文件中:
class FixColumnName < ActiveRecord::Migration
def change
rename_column :table_name, :old_column, :new_column
end
end
评论
可能比重命名列、创建新列并复制内容更好:
通过这种方式,我们可以将内容保存在旧列中
这可能是这一代人:
rails generate migration add_birthdate_to_User birthdate:string
这可能是迁移:
class AddBirthdateToUser < ActiveRecord::Migration[7.0]
def change
add_column :user, :birthdate, :json, default: '[]', null: false
reversible do |dir|
dir.up do
User.update_all('birthdate=birtdate') # rubocop:disable Rails/SkipsModelValidations
end
end
end
end
之后,您必须删除错误的列“Birtdate”
class RemoveBirthdateFromUser < ActiveRecord::Migration[7.0]
def change
remove_column :User, :Birtdate, :json
end
end
评论