我想将一个Sqlite内存数据库转储到带有Marshal的磁盘但是得到下面的错误,这里是完整的测试。用于保存在内存数据库中的Sqlite API似乎只能在C中使用。
require 'sqlite3'
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => ":memory:"
)
ActiveRecord::Schema.define do
create_table :tests do |table|
table.column :word, :string
end
end
class Test < ActiveRecord::Base;end
Test.create(word: 'test')
puts Test.all.length
c = ::ActiveRecord::Base.connection
File.open('sqlite_db.marshal','wb') { |f| f.write(Marshal.dump(c)) }
# => error `dump': can't dump hash with default proc (TypeError)
答案 0 :(得分:1)
您可以使用sqlite3的Backup类。
# populate ActiveRecord here...
sdb = ::ActiveRecord::Base.connection.raw_connection
ddb = SQLite3::Database.new('backup.sqlite3')
b = SQLite3::Backup.new(ddb, 'main', sdb, 'main')
b.step(-1)
b.finish
答案 1 :(得分:0)
目前我使用以下方法,它是我的问题的正确答案,所以我将其打开,也许有人确实找到使用Marshal的解决方案 在这里,我打开了第二个与磁盘数据库的连接,并在之前和之后加载并写入该连接。
require 'sqlite3'
require 'active_record'
class Test < ActiveRecord::Base
establish_connection(
:adapter => "sqlite3",
:database => ":memory:"
)
end
class Test2 < ActiveRecord::Base
establish_connection(
:adapter => "sqlite3",
:database => "testing.db"
)
self.table_name = :tests
end
def db_load
ActiveRecord::Schema.define do
@connection = Test.connection
create_table :tests do |table|
table.column :word, :string
end
end
Test2.all.each do |m|
Test.create m.attributes
end
end
def db_write
Test2.delete_all
Test.all.each do |m|
Test2.create m.attributes
end
end
def db_test klasse
klasse.all.each do |record|
p record
end
end
db_load
db_test Test
Test.create(word: 'test3')
db_write
db_test Test2
给出
-- create_table(:tests)
-> 0.0060s
#<Test id: 1, word: "test">
#<Test id: 2, word: "test2">
#<Test2 id: 1, word: "test">
#<Test2 id: 2, word: "test2">
#<Test2 id: 3, word: "test3">
答案 2 :(得分:0)
这是Max提出的技术示例。 它不是使用Marshal而是使用Activerecord而是使用了ussefull,所以这里仅供参考
require 'sqlite3'
require 'active_record'
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database => ":memory:")
sdb = SQLite3::Database.new(':memory:')
sdb.execute "CREATE TABLE IF NOT EXISTS Cars(Id INTEGER PRIMARY KEY, Name TEXT, Price INT)"
sdb.execute "INSERT INTO Cars VALUES(1,'Audi',52642)"
sdb.execute "INSERT INTO Cars VALUES(2,'Mercedes',57127)"
sdb.execute "INSERT INTO Cars VALUES(3,'Skoda',9000)"
sdb.execute "INSERT INTO Cars VALUES(4,'Volvo',29000)"
sdb.execute "INSERT INTO Cars VALUES(5,'Bentley',350000)"
sdb.execute "INSERT INTO Cars VALUES(6,'Citroen',21000)"
sdb.execute "INSERT INTO Cars VALUES(7,'Hummer',41400)"
sdb.execute "INSERT INTO Cars VALUES(8,'Volkswagen',21600)"
ddb = SQLite3::Database.new('backup.sqlite3')
b = SQLite3::Backup.new(ddb, 'main', sdb, 'main')
b.step(-1)
b.finish
stm = ddb.prepare "SELECT * FROM Cars LIMIT 5"
rs = stm.execute
rs.each do |row|
puts row.join "\s"
end
给出
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
答案 3 :(得分:0)
这里是基于Max编辑的答案的最终解决方案的参考和完整性
require 'sqlite3'
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => ":memory:"
)
ActiveRecord::Schema.define do
create_table :tests do |table|
table.column :word, :string
table.column :index, :string
end
end
class Test < ActiveRecord::Base;end
Test.create(word: 'test', index: 0)
Test.create(word: 'test2', index: 1)
sdb = ::ActiveRecord::Base.connection.raw_connection
ddb = SQLite3::Database.new('backup_sqlite3.db')
backup = SQLite3::Backup.new(ddb, 'main', sdb, 'main')
backup.step(-1)
backup.finish
ddb.execute("select * from tests").each do |record|
p record
end