2013-03-28 3 views
4

:memory:에서 생성 된 SQLite베이스 (sqlalchemy 통해 생성) 작업시 테스트가 실패하고 실제 파일로 생성 된베이스로 작업 할 때 테스트에 통과합니다.sqlite - 파일과 함께 작동합니다. 메모리 :

스크립트가 멀티 스레드입니다. 여러 스레드 (잠금 등)와 함께 SQLite를 사용하는 것이 가장 좋은 방법은 아니지만 SQLite를 사용하여 스크립트의 DB 인터페이스 만 테스트하십시오. 다음과 같이

OperationalError: (OperationalError) 
    no such table: content_info u'INSERT INTO content_info ... 

테스팅 절차 (nose 포함)입니다 : 내가 :memory: 사용하는 경우

, 스크립트는 어떤 테이블이 없다고 불평 다이 설정에 따라서

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 

I 데이터베이스와 컬럼을 작성하십시오. 나는 로그에도 (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는 전에베이스에서 작동하기 시작이었다 실제로 만들어졌습니다. 그러나 create_all 이후에 time.sleep(3)을 추가했는데 작동하지 않았습니다.

앞서 언급했듯이 파일이 가상 파티션 (실제로는 메모리에 있음)에 있더라도 :memory: 대신 파일을 사용하면 작동합니다. 왜 그런가?

답변

9

메모리 내 데이터베이스에 대한 연결을 여러 개 만들 수 없습니다. 대신 :memory:에 새로 연결하면 데이터베이스가 만들어집니다. SQLite documentation에서

:

모든 : 메모리 : 데이터베이스가 다른 모든 구별된다. 따라서 파일 이름이 ": memory :"인 데이터베이스 연결을 두 개 열면 두 개의 독립적 인 메모리 데이터베이스가 만들어집니다.

동일한 디스크립터 문자열로 여러 개의 연결을 만드는 것은 하나의 데이터베이스에 연결한다는 것을 의미합니다.

스레드에 대한 새 연결을 만들므로 테이블을 만들지 않은 데이터베이스를 만듭니다.

+0

흠 나는 같은 엔진을 사용하면 같은베이스에 연결된다고 생각했다. 감사! –

+0

@JakubM .: SQLAlchemy는 연결 풀을 사용하며 엔진은 연결 자체가 아니라 연결 팩토리로 작동합니다. :-) –

관련 문제