ruby-on-rails 导出Rails数据库数据的最佳方法

rqdpfwrv  于 2023-05-02  发布在  Ruby
关注(0)|答案(2)|浏览(87)

轨道5.1
我有一个使用PostgreSQL作为数据库的RAILS应用程序。我想从RAILS透视图导出/转储RAILS数据库数据。所以我独立于数据库。然后,我想使用这个导出/转储文件将数据加载/导入/播种回数据库。
我试过以下的gem:

*seed_dump

它可以工作,但是它不能处理HABTM模型关系。

*yaml_db,可以工作,但yaml格式不是rails db:seed所能理解的格式

8cdiaqws

8cdiaqws1#

下面是一个导出到JSON的实际示例。我使用rake任务来做这类事情。在这个例子中,我转储了一个users表。

namespace :dataexport do
  desc 'export users who have logged in since 2017-06-30'
  task :recent_users => :environment do
    puts "Export users who have logged in since 2017-06-30"

    # Get a file ready, the 'data' directory has already been added in Rails.root
    filepath = File.join(Rails.root, 'data', 'recent_users.json')
    puts "- exporting users into #{filepath}"

    # The key here is to use 'as_json', otherwise you get an ActiveRecord_Relation object, which extends
    # array, and works like in an array, but not for exporting
    users = User.where('last_login > ?', '2017-06-30').as_json

    # The pretty is nice so I can diff exports easily, if that's not important, JSON(users) will do
    File.open(filepath, 'w') do |f|
      f.write(JSON.pretty_generate(users))
    end

    puts "- dumped #{users.size} users"
  end
end

然后导入

namespace :dataimport do
  desc 'import users from recent users dump'
  task :recent_users => :environment do
    puts "Importing current users"

    filepath = File.join(Rails.root, 'data', 'recent_users.json')
    abort "Input file not found: #{filepath}" unless File.exist?(filepath)

    current_users = JSON.parse(File.read(filepath))

    current_users.each do |cu|
      User.create(cu)
    end

    puts "- imported #{current_users.size} users"
  end
end

有时候,作为导入过程的一部分,我会想要一个干净的表来导入,在这种情况下,我会开始taske:

ActiveRecord::Base.connection.execute("TRUNCATE users")

这不是处理超大型表的最佳方式,这些表的行数超过50,000行,并且/或者包含大量文本字段。在这种情况下,数据库本机转储/导入工具会更合适。
为了完整起见,这里有一个HABTM示例。仍然有一个链接表,但它没有模型,所以唯一的方法是使用原始SQL。让我们假设我们的用户有许多角色,反之亦然(用户M:M角色),例如:

class User < ApplicationRecord
  has_and_belongs_to_many :roles
end

class Role < ApplicationRecord
  has_and_belongs_to_many :users
end

必然会有一个名为users_roles的连接表,它有两个列,user_idrole_id。参见HABTM上的Rails指南
要导出,我们必须直接执行SQL:

users_roles = ActiveRecord::Base.connection.execute("SELECT * from users_roles").as_json
# and write the file as before

并执行SQL导入

# read the file, same as before
user_roles.each do |ur|
  ActiveRecord::Base.connection.execute("insert into users_roles (user_id, role_id) values ('#{ur[0]}', '#{ur[1]}')")
end

See this answer for more on inserting with raw SQL

pkmbmrz7

pkmbmrz72#

我同意人们说使用内置的数据库工具来做这件事。或者找出是否有一种方法可以告诉数据库导出到CSV,然后以这种方式导入。

  • 然而 *,如果你真的想要一个数据库不可知的方式,这里有另一种方式:使用自己的API。

我的意思是,在2017年,你的Rails应用程序不应该只输出HTML,还应该输出JSON。也许你想写一个SPA类型的应用程序在未来,或移动的应用程序。确保除了HTML版本之外还有对象的Javascript表示是一个好主意。
因此,如果您的应用中有/项目,请编写一个脚本,请求/projects作为JSON。将每个对象保存为它自己的文件,然后在远程系统中将所有内容都发送回。
如果有任何东西不在JSON表示中(即您没有列出项目上的所有用户),请确保也访问这些端点,并将所有内容保存到单独的JSON文件中。
然后编写一个播放器脚本,将所有这些文件发布到目标服务。
这是一种方法。还有一种方法是在ActiveRecord中完全用Ruby编写它--这可能是某种用户数据导出功能,所以这也可能是一种很棒的方法,但在我看来,“我们能为此构建一个Javascript前端或移动的应用程序吗?通常是在问路之前,“用户能否把自己的数据拿出来”;)

相关问题