私のスクリプトは、で作成されたSQLiteベース ( sqlalchemy経由)を操作するとテストに失敗:memory:
し、物理ファイルで作成されたベースを操作するとテストに合格します。
スクリプトはマルチスレッドです。SQLite を複数のスレッド (ロックなど) で使用するのは最善の方法ではないことはわかっていますが、SQLite を使用してスクリプトの DB インターフェイスのみをテストしています。
を使用する:memory:
と、テーブルがないと不平を言ってスクリプトが停止します。
OperationalError: (OperationalError)
no such table: content_info u'INSERT INTO content_info ...
テスト手順 (鼻付き) は次のとおりです。
def setup_database():
global global_engine
# create database columns
engine = sqlalchemy.create_engine(...)
Base.metadata.create_all(engine)
global_engine = engine
@with_setup(setup_database)
def test_task_spoolers():
check_database_content_from_another_thread()
def check_database_content_from_another_thread():
global global_engine
# from within other thread
# create new session using global_engine
# do some inserts
したがって、セットアップでは、データベースと列を作成します。ログにも表示されます ( echo=True
):
12:41:08 INFO sqlalchemy.engine.base.Engine
CREATE TABLE content_info (...
12:41:08 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
12:41:08 INFO sqlalchemy.engine.base.Engine INSERT INTO
content_info (base_id, request_id, timestamp, ...
12:41:08 INFO sqlalchemy.engine.base.Engine (0, 0, 0, 'dummy_variant',
None, 0)
12:41:08 INFO sqlalchemy.engine.base.Engine ROLLBACK
Exception in thread Thread-1:
Traceback (most recent call last):
OperationalError: (OperationalError)
no such table: content_info u'INSERT INTO ...
私の推測では、スレッド A でベースを作成し、それをスレッド B で使用すると、実際に作成される前に B がベースで操作を開始するということでした。しかし、私は後で追加time.sleep(3)
しましたcreate_all
が、うまくいきませんでした。
そして、前述のように、:memory:
ファイルが仮想パーティションに配置されていても(実際にはメモリ内に)、の代わりにファイルを使用すると機能します。それはなぜですか?