2011-08-01 16 views
5

私は、メモリ内SQLite DBと対話するためにDataMapperをORMとして使用するRubyプログラムを持っています。これはうまくいきましたが、私は最近、新しいDMクラスとそれに対応するテーブルを追加しました。私の驚いたことに、auto_migrate中に物事が爆発しました!ここDataMapperを介したSQLiteメモリDBからのそのようなテーブルエラーはありません

は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:) 

それは、そのテーブルを作成するように見える罰金になりますが、それはわずか数行後に見つけることができません。私は、他のテーブルが見つかって正常に動作することを除いて、DB接続を誤って設定したと思います。 3.7.7.1 @ SQLite3の

  • RVMを経由して

    • ルビー1.9.2p289 1.1.0

    DataMapperの宝石V

  • MacPortsを経由して、なぜこの誰もが知っていますが:

    遊んでいるソフトウェア私はそれについて何ができますか?

    +1

    私は同じ問題を抱えてきたが、さらに、それはスレッド問題がある可能性がありますように見えることでmonkeying後に私の場合では、溶液:( – Ben

    +0

    を発見していない。新しいスレッドに早すぎるのテーブルへのアクセス2つ目のスレッドでデータベースアクセスを移動すると、後で正常に動作するようになりますが、どちらの場合でもログSQLのシーケンスが有効であるように見えます。 – Aaron

    答えて

    4

    問題は、スレッドプールによってDataMapper(またはより正確にはDataObjects、データベースドライバDataMapperが使用する)が自動的に実行されるためです。データベース接続はスレッド間で共有されません。これは、postgresqlやmysql、あるいは 'ファイルをバックアップした'データベースとしてのsqlite3のようなものに対しても(そして、有益でも)うまくいきます。メモリストア内のsqlite3の場合、接続はデータベースです。そのため、追加のスレッドは失敗します。また、一定の時間が経過しても(〜1分?)スレッドが掃除され、データベースも消えてしまいます。

    これがこの場合、簡単に回避できるかどうかはわかりません。これを避けるには、do_sqlite3を変更することができます。基本的に高速でなければならないもう1つの選択肢は、ファイルバックアップされたsqlite3 DBをramdriveで使用することです。

    +0

    これはおそらく聞こえます。今日は "問題のある" DBアクセスパターンに戻って、メモリ内とディスク上の記憶域を交換することで実現します。 – Aaron

    +0

    これは問題ではありませんが、ディスク上のストアから他のすべてのコードが同じであるメモリ内のストア、問題は解決しません。ヘルプありがとうございました! – Aaron

    +1

    余りにも遅く私は知っているが、多分誰かを助けることができる。特別なファイル名 'file :: memory:?cache = shared'を使ってメモリSQLite共有キャッシュを使うことができます。これにより、別々のデータベース接続で同じインメモリ・データベースを共有することができます。 https://www.sqlite.org/inmemorydb.html – Robertiano

    1

    私は私が知っている@Lukas_Skywalker

    の提案によって答えとして私のコメントが遅すぎるコピーが、多分それは、誰かを助けることができます。特別なファイル名file :: memory:?cache = sharedを使用して、メモリSQLite共有キャッシュを使用することができます。これにより、別々のデータベース接続で同じインメモリ・データベースを共有することができます。 sqlite.org/inmemorydb.html

    関連する問題