假设我有2个数据库,main
和temp
,我有一个ActiveRecord类Entry
,对应entries
中的main
表,怎么能我在temp
中创建了一个类似的表。
第一个是使用Entry.connection.execute('show create table #{Entry.table_name}')
并且针对另一个表调用它。 (如果main
和temp
是同一类型的数据库,则有效。)
有更好的方法吗?优选地,不涉及阅读和阅读的一个。调用“创建表”表达式。
例如,使用ActiveRecord :: Schema.define的东西似乎是最好的。但我不确定该怎么做。
感谢。
答案 0 :(得分: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 Migrations Guide提供的内容。
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,add_index等检查数据库并表达其结构来创建此文件。因为这与数据库无关,所以可以将其加载到Active Record支持的任何数据库中。如果您要分发能够针对多个数据库运行的应用程序,这可能非常有用。
但是需要权衡:db / schema.rb不能表达数据库特定的项,例如外键约束,触发器或存储过程。在迁移中,您可以执行自定义SQL语句,但架构转储程序无法从数据库重新构建这些语句。如果您使用这样的功能,那么您应该将架构格式设置为:sql。
不使用Active Record的架构转储器,而是使用特定于数据库的工具(通过db:structure:dump Rake任务)将数据库的结构转储到db / structure.sql中。例如,对于PostgreSQL RDBMS,使用pg_dump实用程序。对于MySQL,此文件将包含各种表的SHOW CREATE TABLE的输出。加载这些模式只是执行它们包含的SQL语句的问题。根据定义,这将创建数据库结构的完美副本。但是,使用:sql架构格式会阻止将架构加载到用于创建架构之外的RDBMS中。
答案 1 :(得分:1)
如果您只想从一个数据库移动到另一个数据库,请使用gem'yaml_db'