RAILS 5.1
我有一个使用PostgreSQL作为数据库的RAILS应用程序。我想从RAILS的角度导出/转储RAILS数据库数据,这样我就不依赖于数据库了。然后,我想使用此导出/转储文件将数据加载/导入/填充回数据库中。
我尝试过以下GEM:
seed_dump
它可以工作,但无法处理HABTM模型关系。yaml_db, 它可以工作,但YAML格式不是rails db:seed所理解的格式。
RAILS 5.1
我有一个使用PostgreSQL作为数据库的RAILS应用程序。我想从RAILS的角度导出/转储RAILS数据库数据,这样我就不依赖于数据库了。然后,我想使用此导出/转储文件将数据加载/导入/填充回数据库中。
我尝试过以下GEM:
seed_dump
它可以工作,但无法处理HABTM模型关系。
yaml_db, 它可以工作,但YAML格式不是rails db:seed所理解的格式。
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
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_id
和role_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
/projects
的脚本作为JSON。将每个对象保存为自己的文件,然后在远程系统中将所有内容发回来。如果JSON表示中没有任何信息(即您未列出项目上的所有用户),请确保也要命中这些端点并将所有内容保存到单独的JSON文件中。然后编写一个播放器脚本,向目标服务POST所有这些文件。