1

假设我有 2 个数据库,main并且,我有一个对应于 中的表temp的 ActiveRecord 类,如何在 中创建类似的表。Entryentriesmaintemp

第一个刺是Entry.connection.execute('show create table #{Entry.table_name}')针对另一个表使用和调用它。(如果main并且temp是同一种数据库,则有效)。

有更好的方法吗?最好是不涉及读取和调用“创建表”表达式的一种。

例如,带有 ActiveRecord::Schema.define 的东西似乎是最好的。但我不确定该怎么做。

谢谢。

4

2 回答 2

2

快速谷歌搜索后,我没有找到没有原始 SQL 的现成方法。但是,您可以通过模仿所做的事情来制定自己的解决方案annotate_models

来自https://github.com/ctran/annotate_models/blob/master/lib/annotate/annotate_models.rb

# Use the column information in an ActiveRecord class
# to create a comment block containing a line for
# each column. The line contains the column name,
# the type (and length), and any optional attributes
def get_schema_info(klass, header, options = {})
  info = "# #{header}\n#\n"
  info << "# Table name: #{klass.table_name}\n#\n"

  max_size = klass.column_names.collect{|name| name.size}.max + 1
  klass.columns.each do |col|
    attrs = []
    attrs << "default(#{quote(col.default)})" unless col.default.nil?
    attrs << "not null" unless col.null
    attrs << "primary key" if col.name == klass.primary_key

    col_type = col.type.to_s
    if col_type == "decimal"
      col_type << "(#{col.precision}, #{col.scale})"

此外,您可能想阅读ActiveRecord 迁移指南所提供的内容。

ActiveRecord::Schema.define(:version => 20080906171750) do
  create_table "authors", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

该文件是通过检查数据库并使用 create_table、a​​dd_index 等表示其结构来创建的。因为这是独立于数据库的,所以它可以加载到 Active Record 支持的任何数据库中。如果您要分发能够针对多个数据库运行的应用程序,这可能非常有用。

然而,有一个权衡:db/schema.rb 不能表达数据库特定的项目,例如外键约束、触发器或存储过程。虽然在迁移中您可以执行自定义 SQL 语句,但模式转储程序无法从数据库中重构这些语句。如果您正在使用这样的功能,那么您应该将架构格式设置为 :sql。

将使用特定于数据库的工具(通过 db:structure:dump Rake 任务)将数据库的结构转储到 db/structure.sql 中,而不是使用 Active Record 的模式转储器。例如,对于 PostgreSQL RDBMS,使用 pg_dump 实用程序。对于 MySQL,此文件将包含各种表的 SHOW CREATE TABLE 的输出。加载这些模式只是执行它们包含的 SQL 语句的问题。根据定义,这将创建数据库结构的完美副本。但是,使用 :sql 模式格式将阻止将模式加载到用于创建它的 RDBMS 之外的 RDBMS 中。

于 2012-04-13T00:14:57.247 回答
1

如果您只想从一个数据库移动到另一个数据库,请使用 gem 'yaml_db'

于 2012-04-13T04:16:30.853 回答