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

Ray*_*ger 17 python sqlite

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

问题如何在python中浏览内存sqlite数据库似乎有关,但它侧重于如何在内存数据库中使用基于磁盘的浏览工具.问题如何在Python中将内存中的SQLite数据库复制到另一个内存中的SQLite数据库?也是相关的,但它是Django特有的.

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

肯定有更好的办法!

Ray*_*ger 14

如何在Python sqlite3中将现有db文件加载到内存中的答案提供了重要的线索.基于该答案,这里是该代码的简化和概括.

它消除了消除不必要的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()
Run Code Online (Sandbox Code Playgroud)


Mik*_*son 5

坦率地说,我不会在内存数据库方面混得太多,除非你确实需要一个索引结构,你知道它总是完全适合可用内存。SQLite 在其 I/O 方面非常聪明,尤其是当您将所有内容(包括读取...)包装到事务中时,您应该这样做。它将非常有效地将内容保存在内存中,因为它正在操作从根本上存在于外部存储上的数据结构,但它永远不会耗尽内存(也不会占用太多内存)。我认为,RAM真正的工作更好地为“缓冲区”的而不是存储数据的主要场所......尤其是在一个虚拟存储 环境,其中一切都必须被视为“无论如何都由外部存储支持”。

  • 我的用例是一个长时间运行的进程(一个 Web 服务),数据完全在 RAM 中(因此在操作期间根本没有磁盘 i/o)。数据很少发生变异,但我确实运行频繁的查询。磁盘上的版本只是为了使数据在系统重新启动后仍然存在。 (2认同)