如何将 .yml 文件中的数据加载到数据库?

发布于 2024-09-06 13:31:53 字数 809 浏览 6 评论 0原文

有一个表 questions 和一个数据文件 questions.yml。假设没有“问题”模型。

“questions.yml”有一些来自表的重新编码转储。

---
questions_001:
  title: ttt1
  content: ccc1
questions_002:
  title: ttt2
  content: ccc2

我想从 yml 文件加载数据,将它们插入数据库。但我不能使用 rake db:fixtures:load ,因为它会将内容视为“erb”模板,这不是我想要的

所以我想编写另一个 rake 任务来加载手动数据。

我可以通过以下方式读取记录:

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
   YAML::load(file).each do |record|
      # how to insert the record??
   end
end

但我不知道如何插入它们。


编辑:

我已经尝试过:

Class.new(ActiveRecord::Base).create(record)

但是

class Dummy < ActiveRecord::Base {}
Dummy.create(rcord)

没有任何内容插入到数据库中

There is a table questions, and a data file questions.yml. Assume there is no 'Question' model.

'questions.yml' has some recodes dump from the table.

---
questions_001:
  title: ttt1
  content: ccc1
questions_002:
  title: ttt2
  content: ccc2

I want to load the data from the yml file, insert them to database. But I can't use rake db:fixtures:load, because it will treat the content as 'erb' template, which is not want I want

So I want to write another rake task, to load the data manually.

I can read the records by:

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
   YAML::load(file).each do |record|
      # how to insert the record??
   end
end

But I don't know how to insert them.


Edit:

I have tried:

Class.new(ActiveRecord::Base).create(record)

and

class Dummy < ActiveRecord::Base {}
Dummy.create(rcord)

But nothing inserted to database

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最笨的告白 2024-09-13 13:31:53

将日期从 yml 文件加载到 records 后尝试此操作:

class Question < ActiveRecord::Base
  # Question model just to import the yml file
end
records.each { |record| Question.create(record) }

您可以简单地创建一个仅用于导入的模型。您不需要创建 app/models/question.rb。只需在负责导入的脚本中编写上面的代码即可。

更新:

您可以使用以下功能:

def create_class(class_name, superclass, &block)
  klass = Class.new superclass, &block
  Object.const_set class_name, klass
end

来源

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
  YAML::load(file).each do |record|
    model_name = table_name.singularize.camelize
    create_class(model_name, ActiveRecod::Base) do
      set_table_name table_name.to_sym
    end
    Kernel.const_get(model_name).create(record)
  end
end

使用直接连接您可以使用以下命令:

ActiveRecord::Base.connection.execute("YOUR SQL CODE")

Try this after loading the date from the yml file to records:

class Question < ActiveRecord::Base
  # Question model just to import the yml file
end
records.each { |record| Question.create(record) }

You can simply create a model just for importing. You don't need to create the app/models/question.rb. Just write the code above in the script responsible for the importing.

UPDATE:

You can use the following function:

def create_class(class_name, superclass, &block)
  klass = Class.new superclass, &block
  Object.const_set class_name, klass
end

source

File.open("#{RAILS_ROOT}/db/fixtures/#{table_name}.yml", 'r') do |file|
  YAML::load(file).each do |record|
    model_name = table_name.singularize.camelize
    create_class(model_name, ActiveRecod::Base) do
      set_table_name table_name.to_sym
    end
    Kernel.const_get(model_name).create(record)
  end
end

To use the connection directly you can use the following:

ActiveRecord::Base.connection.execute("YOUR SQL CODE")
恋你朝朝暮暮 2024-09-13 13:31:53

感谢 @jigfox 的回答,它得以正常工作。现在必须对 Rails 4 的完整实现进行一些修改。

table_names = Dir.glob(Rails.root + 'app/models/**.rb').map { |s| Pathname.new(s).basename.to_s.gsub(/\.rb$/,'') }    

table_names.each do |table_name|
  table_name = table_name.pluralize
  path = "#{Rails.root}/db/fixtures/#{table_name}.yml"
  if File.exists?(path)
    File.open(path, 'r') do |file|
      y = YAML::load(file)
      if !y.nil? and y
        y.each do |record|
          model_name = table_name.singularize.camelize
          rec = record[1] 
          rec.tap { |hs| hs.delete("id") }
          Kernel.const_get(model_name).create(rec)
        end
      end
    end
  end
end

Got it working thanks to @jigfox 's answer. Had to modify a bit for the full implementation now with Rails 4.

table_names = Dir.glob(Rails.root + 'app/models/**.rb').map { |s| Pathname.new(s).basename.to_s.gsub(/\.rb$/,'') }    

table_names.each do |table_name|
  table_name = table_name.pluralize
  path = "#{Rails.root}/db/fixtures/#{table_name}.yml"
  if File.exists?(path)
    File.open(path, 'r') do |file|
      y = YAML::load(file)
      if !y.nil? and y
        y.each do |record|
          model_name = table_name.singularize.camelize
          rec = record[1] 
          rec.tap { |hs| hs.delete("id") }
          Kernel.const_get(model_name).create(rec)
        end
      end
    end
  end
end
月下伊人醉 2024-09-13 13:31:53

这会将夹具加载到当前的 RAILS_ENV 中,默认情况下,该环境是开发环境。

$ rake db:fixtures:load

This loads fixtures into the current RAILS_ENV, which, by default, is development.

$ rake db:fixtures:load
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文