使用 Marshal 将 Sqlite 内存数据库转储到磁盘
Dump a Sqlite memory database to disk with Marshal
我想使用 Marshal 将 Sqlite 内存数据库转储到磁盘,但出现以下错误,这里是完整测试。用于保存在内存数据库中的 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)
可以使用sqlite3的Backup class.
# 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
目前我使用以下方法,它不是我问题的正确答案,所以我将保持打开状态,也许有人确实使用 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">
这里是 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
此处基于最大编辑答案的最终解决方案供参考和完整性
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
我想使用 Marshal 将 Sqlite 内存数据库转储到磁盘,但出现以下错误,这里是完整测试。用于保存在内存数据库中的 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)
可以使用sqlite3的Backup class.
# 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
目前我使用以下方法,它不是我问题的正确答案,所以我将保持打开状态,也许有人确实使用 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">
这里是 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
此处基于最大编辑答案的最终解决方案供参考和完整性
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