Rails:由于模式的变化,如何使用迁移来修改数据



我有以下两个迁移:

一、将列contextual_page_number添加到transcripts表:

class AddContextualPageNumberToTranscripts < ActiveRecord::Migration[5.2]
def change
add_column :transcripts, :contextual_page_number, :integer, default: 1
end
end

第二,根据另一列的值更改上一个添加列contextual_page_number的值:

class ChangePageOffsetAndContextualPageNumberOfTranscripts < ActiveRecord::Migration[5.2]
def up
Firm.all.find_in_batches do |group|
group.each do |firm|
Apartment::Tenant.switch(firm.tenant) do
Transcript.where.not(page_offset: 0).each do |transcript|
transcript.update(
contextual_page_number: ((transcript.page_offset - 1) * -1),
page_offset: 1
)
end
end
end
end
end
def down
..
end
end

运行迁移后,我得到未知属性contextual_page_number错误。

==20211108132509 AddContextualPageNumberToTranscripts:迁移=============--add_column(:transcripts,:context_page_number,:integer,{:default=>1}(->0.0095秒===20211108132509 AddContextualPageNumberToTranscripts:migrated(0.0096s(===

===20220113095658 ChangePageOffsetAndContextualPageNumberOfTranscripts:迁移rails中止!StandardError:发生了一个错误,这一次以及以后的所有错误迁移已取消:

Transcript的未知属性"contextual_page_number"。

我甚至尝试过reset_column_information,但运气不佳:

Apartment::Tenant.switch(firm.tenant) do
Transcript.connection.schema_cache.clear!
Transcript.reset_column_information
..
end

任何线索都会有很大帮助,谢谢。

正如其中一个答案中所提到的,我在add_column之后尝试了reset_column_information,但没有成功。最后,SQL出手相救。。

sql_cmd = "UPDATE transcripts
SET contextual_page_number = ((page_offset - 1) * -1),
page_offset = 1
WHERE page_offset != 0"
Transcript.connection.execute(sql_cmd)

您需要两个迁移文件。首先,尝试运行迁移并检查表transcriptsschema.rb,并验证是否正在添加新添加的列contextual_page_number

确定添加了新列后,再次创建一个新的迁移,例如:MigrateTransriptsCloningsData,然后在up块中添加所需的更改,然后执行db:migrate以更新所需的修改。

我的选择是添加一个新的rake任务并执行它。就像bundle exec rake migrate_transcripts_data:start一样,选择权属于你,而不是将该逻辑保留在db/migrate/your_new_migration_file中。

如果您想在迁移中使用模型,

reset_column_information应该是解决这类问题的正确方法。不过,这并非没有问题。

我怀疑问题是你不知怎么说来的太迟了。把它放在第二次迁移的up方法中,或者放在第一次迁移的add_column之后。

我可能认为问题在Apartment.tenant_names中。在第二次迁移中,您通过Apartment::Tenant.switch(firm.tenant)切换租户,但我在第一次迁移中没有看到类似的情况。租户名称可能在数据库中,而不是在配置文件中。我非常确信,您可能会在以前的迁移中找到适当的add_column的示例。

不要使用结构迁移来修改数据。

使用rake任务或数据迁移gem。

此外,如果不能确保自动数据迁移在生产服务器上按预期工作,请不要使用自动数据迁移。始终在修改前存储数据,并编写修改回滚代码。

最新更新