sqlite - 与文件一起工作,死于:内存:

Jak*_* M. 6 python sqlite sqlalchemy

在使用创建的SQLite base(通过sqlalchemy)时,我的脚本未:memory:通过测试,并且在使用使用物理文件创建的基础时通过测试.

该脚本是多线程的.我知道将SQLite用于多个线程(锁定等)并不是最好的想法,但我只使用SQLite来测试脚本的DB接口.

当我使用时:memory:,脚本死于抱怨没有表:

OperationalError: (OperationalError)
    no such table: content_info u'INSERT INTO content_info ...
Run Code Online (Sandbox Code Playgroud)

测试程序(带鼻子)如下:

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
Run Code Online (Sandbox Code Playgroud)

因此,在建立我创建数据库和列.我也可以在logs(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 ...
Run Code Online (Sandbox Code Playgroud)

我的猜测是,当我在线程A中创建基础,然后我在线程B中使用它时,B在实际创建之前就开始在基础上运行.但是,我time.sleep(3)之后补充create_all说它没有用.

并且,如前所述,它在我使用文件而不是文件时工作:memory:,即使文件放在虚拟分区上(因此,实际上在内存中).知道为什么会这样吗?

Mar*_*ers 11

您无法创建与内存数据库的多个连接.而是:memory:创建数据库的新连接.

SQLite文档:

Every:memory:数据库彼此不同.因此,打开两个数据库连接,每个数据库连接的文件名为":memory:",将创建两个独立的内存数据库.

这与磁盘数据库不同,在磁盘数据库中,使用相同的连接字符串创建多个连接意味着您将连接到一个数据库.

您正在为该线程创建新连接,从而创建一个没有创建表的数据库.