跨线程的SQLite临时表

时间:2014-07-17 16:00:02

标签: python sqlite sqlalchemy

我使用SQLAlchemy的declarative_base来描述我的数据模式。在我的用例中,我将每天将大量数据插入到数据库中,然后在事后使用和操作此数据作为业务对象。

我最初的方法是使用ORM方法设置表格,我的大多数“业务逻辑”都会与之交互,但是我使用Core进行插入。这有几个原因。首先,我必须使用数百个单独的查询通过Web服务获取数据。每个查询将转换为数百/数千个数据库行。通过许多表和许多ForeignKeys的高度规范化模式,我只想到最简单的方法如下:

  1. 创建临时登台表,以便在数据通过Web服务进入时进行批量插入。一个线程将专门用于通过Queue接收查询结果并插入表中。
  2. 将所有数据插入临时表后,我将运行多个insert().from_select(...)查询来处理数据完整性并将所有内容放在适当的位置。这将通过单独的线程
  3. 完成
  4. 这是一个一天一次的过程,一旦完成,我的应用程序使用ORM的“业务逻辑”方面将可用并作为单独的应用程序执行它
  5. 我的问题是在单个连接上维护临时表。我似乎失去了它,无法理解为什么我跟着the approach in the docs

    相关的代码:

    db模块包含引擎和辅助函数,以确保启用ForeignKey支持:

    engine = create_engine('sqlite:///%s' % SQLDB, poolclass=StaticPool)
    
    def get_connection():
        conn = engine.connect()
        conn.execute('pragma foreign_keys=on')
        return conn
    

    主线程创建表:

    db.StagingTable.__table__.create(db.engine)
    

    每个工作线程(有两个,一个正在执行插入,一个执行INSERT INTO SELECT工作)使用辅助函数来获取连接:

    self.cn = db.get_connection()
    

    部分追溯:

      File "C:\FAST\Python266\lib\site-packages\sqlalchemy\engine\base.py", line 917, in _execute_context
        context)
      File "C:\FAST\Python266\lib\site-packages\sqlalchemy\engine\default.py", line 432, in do_executemany
        cursor.executemany(statement, parameters)
    OperationalError: (OperationalError) no such table: staging u'INSERT INTO staging
    

    我在这里缺少什么?我的印象是StaticPool将维持一个可以传递给不同线程的开放连接。

1 个答案:

答案 0 :(得分:0)

您必须至少执行一个Session.commit()才能实际向数据库写入内容,包括创建表的DDL。

您看到的问题是将INSERT写入尚未CREATE的表格中。