Comment charger un fichier db existant en mémoire dans Python sqlite3?

j'ai un fichier sqlite3 db existant, sur lequel je dois faire des calculs approfondis. Faire les calculs à partir du fichier est douloureusement lent, et comme le fichier n'est pas grand (~ 10 MB ), il ne devrait pas y avoir de problème pour le charger en mémoire.

Existe-t-il un moyen pythonique de charger le fichier existant en mémoire afin d'accélérer les calculs?

50

7 réponses

Voici l'extrait que j'ai écrit pour mon application flasque:

import sqlite3
from StringIO import StringIO

def init_sqlite_db(app):
    # Read database to tempfile
    con = sqlite3.connect(app.config['SQLITE_DATABASE'])
    tempfile = StringIO()
    for line in con.iterdump():
        tempfile.write('%s\n' % line)
    con.close()
    tempfile.seek(0)

    # Create a database in memory and import from tempfile
    app.sqlite = sqlite3.connect(":memory:")
    app.sqlite.cursor().executescript(tempfile.read())
    app.sqlite.commit()
    app.sqlite.row_factory = sqlite3.Row
92
répondu Cenk Alti 2012-06-01 19:46:07

sqlite3.Connection.iterdump "[renvoie un itérateur pour Dumper la base de données dans un format de texte SQL. Utile pour sauvegarder une base de données en mémoire pour une restauration ultérieure. Cette fonction fournit les mêmes fonctionnalités que la commande .dump dans le shell sqlite3."

obtenez un tel itérateur et dump la base de données basée sur le disque dans une base de données basée sur la mémoire, et vous êtes prêt à calculer. Quand le calcul est fait, il suffit de dumper l'autre chemin vers le disque.

16
répondu Fred Foo 2014-05-05 12:14:31

vous devriez D'abord essayer de découvrir ce qui cause la lenteur que vous observez. Êtes-vous à l'écriture dans les tables? Est-ce que vos Écritures sont assez grandes transactions de sorte que vous ne sauvez pas les résultats temporaires inutiles sur le disque? Pouvez-vous changer écrit pour aller à des tables temporaires (avec pragma temp_store=memory )? Pouvez-vous vivre avec pragma synchronous=off ?

Je ne pense pas que cette fonctionnalité soit exposée dans le Python module, mais sqlite a une API de sauvegarde qui ressemble exactement à ce que vous demandez: une façon de copier d'une base de données à une autre (dont l'une ou l'autre peut être une base de données en mémoire) qui fonctionne assez automatiquement sans aucune énumération de tableaux visible par l'utilisateur. (Peut-être APSW expose ceci?)

une autre option est de créer un disque ram (si vous avez le contrôle suffisant de l'environnement) et d'y copier le fichier.

8
répondu Jouni K. Seppänen 2010-10-03 16:49:35

cela a déjà été répondu auparavant, y compris des exemples de code à en python, Comment puis-je charger un SQLite db complètement en mémoire avant de me connecter à celui-ci?

vous ne mentionnez pas le système d'exploitation, mais un gotcha de Windows XP est qu'il est par défaut à un cache de fichier 10MB, peu importe combien de mémoire vous avez. (Cela avait du sens à L'époque où les systèmes venaient avec 64 Mo, etc.). Ce message comporte plusieurs liens:

http://marc.info/?l=sqlite-users&m=116743785223905&w=2

4
répondu Roger Binns 2017-05-23 12:02:38

Voici une façon relativement simple de lire un db SQLite dans la mémoire. Selon vos préférences en ce qui concerne la manipulation des données, vous utilisez soit Pandas dataframe ou écrivez votre table à une base de données sqlite3 en mémoire. De même, après avoir manipulé vos données, vous utilisez le même df.approche to_sqlite pour stocker vos résultats dans une table db.

import sqlite3 as lite
from pandas.io.sql import read_sql
from sqlalchemy import create_engine

engine = create_engine('sqlite://')
c = engine.connect()
conmem = c.connection
con = lite.connect('ait.sqlite', isolation_level=None) #Here is the connection to <ait.sqlite> residing on disk
cur = con.cursor()
sqlx = 'SELECT * FROM Table'
df = read_sql(sqlx, con, coerce_float=True, params=None) 

#Read SQLite table into a panda dataframe
df.to_sql(con=conmem, name='Table', if_exists='replace', flavor='sqlite')
4
répondu Crooner 2017-01-09 13:38:58

si nous devons utiliser un emballage python,alors il n'y a pas de meilleure solution que les deux solutions pass, read and write. mais à partir de la version 3.7.17, SQLite a l'option d'accéder au contenu du disque directement en utilisant la mémoire cartographiée I / O. sqlite mmap

si vous voulez utiliser mmap,vous devez utiliser l'interface C car aucun wrapper ne le fournit.

et il y a une autre solution matérielle,le disque mémoire.ensuite, vous avez la fichier IO pratique et la vitesse de la mémoire.

3
répondu obgnaw 2017-12-11 02:56:17

sqlite prend en charge les bases de données en mémoire.

en python, vous utiliseriez un : mémoire: nom de base de données pour cela.

peut-être pourriez-vous ouvrir deux bases de données (une à partir du fichier, une vide en mémoire), tout migrer de la base de données de fichiers dans la mémoire, puis utiliser la base de données en mémoire pour faire des calculs.

0
répondu jedi_coder 2010-10-03 14:35:29