Help us learn about your current experience with the documentation. Take the survey.

交换表

有时你需要用一张表替换另一张表。例如,在迁移非常大的表中的数据时,通常更好的做法是创建该表的副本,然后在后台将数据插入并迁移到这个新表中。

例如,要将名为 events 的表与名为 events_for_migration 的表进行交换,你需要:

  1. events 重命名为 events_temporary
  2. events_for_migration 重命名为 events
  3. events_temporary 重命名为 events_for_migration

Rails 允许你使用 rename_table 方法来执行此操作:

rename_table :events, :events_temporary
rename_table :events_for_migration, :events
rename_table :events_temporary, :events_for_migration

只要这 3 个 rename_table 调用在同一个数据库事务中执行,就不需要任何停机时间。Rails 默认为迁移使用数据库事务,但如果不是这样,你需要手动启动一个事务:

Event.transaction do
  rename_table :events, :events_temporary
  rename_table :events_for_migration, :events
  rename_table :events_temporary, :events_for_migration
end

交换后,你必须重置新表的主键。对于 PostgreSQL,你可以使用 reset_pk_sequence! 方法,如下所示:

reset_pk_sequence!('events')

如果不重置主键,新创建的行将从 ID 值 1 开始。根据现有数据,这可能导致重复键约束的出现,从而阻止用户创建新数据。