在磁盘数据库和快速内存数据库之间来回移动?

时间:2015-07-02 18:12:10

标签: python sqlite

Python sqlite3 :memory:选项提供比等效的磁盘数据库更快的查询和更新。如何将基于磁盘的数据库加载到内存中,对其执行快速操作,然后将更新后的版本写回磁盘?

问题How to browse an in memory sqlite database in python似乎有关,但它侧重于如何在内存数据库中使用基于磁盘的浏览工具。问题How can I copy an in-memory SQLite database to another in-memory SQLite database in Python?也是相关的,但它特定于Django。

我目前的解决方案是一次一个地读取所有表,从基于磁盘的数据库到元组列表,然后手动重新创建内存数据库的整个数据库模式,然后加载从元组列表到内存数据库的数据。对数据进行操作后,过程就会逆转。

必须有更好的方法!

2 个答案:

答案 0 :(得分:13)

How to load existing db file to memory in Python sqlite3?的回答提供了重要的线索。基于该答案,这是对该代码的简化和概括。

它消除了对 StringIO 的不必要使用,并打包成可重复使用的形式,用于读取和写入内存数据库。

import sqlite3

def copy_database(source_connection, dest_dbname=':memory:'):
    '''Return a connection to a new copy of an existing database.                        
       Raises an sqlite3.OperationalError if the destination already exists.             
    '''
    script = ''.join(source_connection.iterdump())
    dest_conn = sqlite3.connect(dest_dbname)
    dest_conn.executescript(script)
    return dest_conn

if __name__ == '__main__':
    from contextlib import closing

    with closing(sqlite3.connect('pepsearch.db')) as disk_db:
        mem_db = copy_database(disk_db)

    mem_db.execute('DELETE FROM documents WHERE uri="pep-3154"')
    mem_db.commit()

    copy_database(mem_db, 'changed.db').close()

答案 1 :(得分:4)

坦率地说,我不会对内存数据库愚弄太多,除非你确实需要一个你知道它总是完全适合可用内存的索引结构。 SQLite对其I / O非常聪明,特别是当您将所有(包括读取...)包装到事务中时,就像您应该的那样。它将非常有效地将内容保存在内存中,因为它正在操纵基本上存在于外部存储上的数据结构,但它永远不会耗尽内存(也不会占用太多内存)。我认为RAM真的 更好地作为“缓冲区”工作,而不是存储数据的主要场所...... 尤其虚拟存储中