如何通过 Rails 迁移克隆数据库表?

Posted

技术标签:

【中文标题】如何通过 Rails 迁移克隆数据库表?【英文标题】:How might you clone a database table via Rails migration? 【发布时间】:2010-12-05 08:37:47 【问题描述】:

我想要一个迁移来创建一个现有表的克隆,只需为名称添加后缀,包括原始表中的所有索引。

所以有一个“snapshots”表,我想创建“snapshots_temp”作为表的精确副本(不是数据,只是表架构,但包括索引)。

我可以从 schema.rb 文件中复制并粘贴块并手动重命名它。

但我不确定在应用此迁移时 schema.rb 中的定义是否仍然准确。其他开发人员可能已经更改了表,我不想更新我的迁移脚本。

那么我如何在运行时获取表的架构?本质上,“rake schema:dump”如何对表进行逆向工程,以便我可以在迁移中做同样的事情? (但更改表名)。

【问题讨论】:

【参考方案1】:

尝试使用纯 SQL 来完成。这会做你想做的事:

CREATE TABLE new_tbl LIKE orig_tbl;

【讨论】:

好电话。 “使用 LIKE 根据另一个表的定义创建一个空表,包括原表中定义的任何列属性和索引”dev.mysql.com/doc/refman/5.1/en/create-table.html 适用于 MySQL(可能还有大多数数据库),但如果您使用 Sqlite,它将无法正常工作。我在开发环境中遇到了这个问题。生产很好(它是 MySQL)。 非常感谢。请注意,您复制的表将获得索引,但不会获得任何外键。您必须分别重新创建它们。 PostgreSQL 用户:CREATE TABLE new_tbl (LIKE orig_tbl INCLUDING DEFAULTS INCLUDING INDEXES);INCLUDING ALL to clone everything 这是另一个帖子中的有用答案,用于克隆和复制所有数据到另一个表的两个命令:***.com/a/3280042/513739【参考方案2】:

在 Rails 4 和 PostgreSQL 中,创建一个新的迁移并插入:

ActiveRecord::Base.connection.execute("CREATE TABLE clone_table_name AS SELECT * FROM source_table_name;")

这将创建具有原始表的精确结构的克隆,并使用旧值填充新表。

更多信息:http://www.postgresql.org/docs/9.0/static/sql-createtableas.html

【讨论】:

小心这一点,因为它也会复制 ID 列,并且不会将其设置为新表中的主要。 而且它不会重新创建索引。【参考方案3】:

这样就可以了。它并不完美,因为它不会复制表选项或索引。如果您确实设置了任何表选项,则必须手动将它们添加到此迁移中。

要复制索引,您必须制定一个 SQL 查询来选择它们,然后将它们处理成新的 add_index 指令。这有点超出我的认知。但这适用于复制结构。

class CopyTableSchema < ActiveRecord::Migration
  def self.up
    create_table :new_models do |t|
      Model.columns.each do |column|
        next if column.name == "id"   # already created by create_table
        t.send(column.type.to_sym, column.name.to_sym,  :null => column.null, 
          :limit => column.limit, :default => column.default, :scale => column.scale,
          :precision => column.precision)
      end
    end

    # copy data 

    Model.all.each do |m|
      NewModel.create m.attributes
    end
  end

  def self.down
    drop_table :new_models
  end
end

【讨论】:

> 它不会复制表选项或索引 谢谢,但索引是必需的。 大声笑我想要一些没有索引的克隆【参考方案4】:

将项目 db/schema.rb 中的表条目直接复制到迁移中。只需更改表名即可。

【讨论】:

【参考方案5】:

看起来这个逻辑包含在 ActiveRecord::SchemaDumper 中,但它只公开了一个一体化的“转储”方法,您不能只转储一个特定的表(the "table" method 是私有的)。

【讨论】:

以上是关于如何通过 Rails 迁移克隆数据库表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 3 中迁移数据?

如何使用 Rails 迁移删除列

如何在 Rails 应用程序中克隆表并保持结构同步?

如何在 Rails 迁移中将列(包含内容)移动到另一个表?

如何编写迁移以重命名 Rails 中的 ActiveRecord 模型及其表?

在 rails upgrade 迁移条目从模式迁移表中删除后