通过DataMapper从SQLite内存DB中没有这样的表错误

时间:2011-08-01 20:51:15

标签: ruby sqlite datamapper

我有一个Ruby程序,它使用DataMapper作为ORM与内存中的SQLite DB进行通信。这一直很好,但我刚刚添加了一个新的DM类和相应的表。令我惊讶的是,在auto_migrate中,事情现在爆炸了!

这是DataMapper生成的SQL:

~ (0.000390) PRAGMA table_info("sensationd_channels")
~ (0.000010) PRAGMA table_info("sensationd_commands")
~ (0.000009) PRAGMA table_info("sensationd_configurations")
~ (0.000052) PRAGMA table_info("sensationd_measurements")
~ (0.000028) SELECT sqlite_version(*)
~ (0.000035) DROP TABLE IF EXISTS "sensationd_channels"
~ (0.000009) PRAGMA table_info("sensationd_channels")
~ (0.000423) CREATE TABLE "sensationd_channels" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "channel" INTEGER NOT NULL, "name" VARCHAR(50), "precision" INTEGER DEFAULT 11, "gain" INTEGER DEFAULT 1, "differential" BOOLEAN DEFAULT 'f', "configuration_id" INTEGER NOT NULL)
~ (0.000191) CREATE INDEX "index_sensationd_channels_configuration" ON "sensationd_channels" ("configuration_id")
~ (0.000015) DROP TABLE IF EXISTS "sensationd_commands"
~ (0.000009) PRAGMA table_info("sensationd_commands")
~ (0.000153) CREATE TABLE "sensationd_commands" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "action" INTEGER DEFAULT 1, "complete" BOOLEAN DEFAULT 'f', "issued_at" TIMESTAMP, "completed_at" TIMESTAMP)
~ (0.000015) DROP TABLE IF EXISTS "sensationd_configurations"
~ (0.000009) PRAGMA table_info("sensationd_configurations")
~ (0.000155) CREATE TABLE "sensationd_configurations" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "created_on" TIMESTAMP, "modified_on" TIMESTAMP, "name" VARCHAR(50) NOT NULL, "active" BOOLEAN)
~ (0.000015) DROP TABLE IF EXISTS "sensationd_measurements"
~ (0.000009) PRAGMA table_info("sensationd_measurements")
~ (0.000152) CREATE TABLE "sensationd_measurements" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "timestamp" TIMESTAMP, "measurement" VARCHAR(65535) NOT NULL, "channel_id" INTEGER NOT NULL, "channel_configuration_id" INTEGER NOT NULL)
~ (0.000175) CREATE INDEX "index_sensationd_measurements_channel" ON "sensationd_measurements" ("channel_id", "channel_configuration_id")
~ (0.000083) SELECT "id", "created_on", "modified_on", "name", "active" FROM "sensationd_configurations" WHERE "active" = 't' ORDER BY "id" LIMIT 1
~ (0.000073) INSERT INTO "sensationd_configurations" ("created_on", "modified_on", "name", "active") VALUES ('2011-08-01T12:36:18-07:00', '2011-08-01T12:36:18-07:00', 'Test U6-Pro Configuration, differential.', 't')
~ (0.000109) SELECT "id", "action", "complete", "issued_at", "completed_at" FROM "sensationd_commands" ORDER BY "issued_at" DESC LIMIT 1
~ (0.000086) INSERT INTO "sensationd_channels" ("channel", "name", "precision", "gain", "differential", "configuration_id") VALUES (0, '0', 11, 0, 't', 1)
~ no such table: sensationd_commands (code: 1, sql state: , query: SELECT "id", "action", "complete", "issued_at", "completed_at" FROM "sensationd_commands" ORDER BY "issued_at" DESC LIMIT 1, uri: sqlite3::memory:?scheme=sqlite&user=&password=&host=&port=&query=&fragment=&adapter=sqlite3&path=:memory:)

看起来它创建表格很好,但之后几行就找不到了。我认为我错误配置了数据库连接,除了找到其他表并且工作正常。

正在播放的软件:

  • Ruby 1.9.2p289 via RVM
  • SQLite3 @ 3.7.7.1通过MacPorts
  • DataMapper gem v 1.1.0

是否有人知道为什么会出现这种情况,以及我能做些什么呢?

2 个答案:

答案 0 :(得分:4)

问题是,我怀疑,由于线程池,DataMapper(或更准确地说,DataObjects,DataMapper使用的数据库驱动程序)会自动执行。线程之间不共享数据库连接。这对于像postgresql或mysql甚至sqlite3这样的“文件支持”数据库来说是好的(甚至是有益的)。对于内存存储中的sqlite3,连接数据库。因此,额外的线程将失败。此外,经过一段时间不活动(约1分钟?)后,线程将被清除,数据库也会消失。

如果是这样,我不确定是否有轻松的解决方法。您可以修改do_sqlite3以避免这种情况。另一个应该基本上同样快的替代方案是在ramdrive上使用文件支持的sqlite3数据库。

答案 1 :(得分:1)

我通过@Lukas_Skywalker的建议将我的评论复制为答案

我知道太晚了,但也许它可以帮助别人。您可以使用特殊文件名文件:: memory:?cache = shared来使用内存SQLite共享缓存。这允许单独的数据库连接共享相同的内存数据库。 sqlite.org/inmemorydb.html