Question

J'ai des données stockées dans une base de données que je veux traiter. accès DB est très lent, donc j'ai décidé de charger toutes les données dans un dictionnaire avant tout traitement. Cependant, en raison de la taille énorme des données stockées, je reçois une erreur de dépassement de mémoire (je vois plus de 2 concerts utilisés). Je décide donc d'utiliser une structure de données sur le disque, et a découvert que l'utilisation shelve est une option. Voici ce que je fais (pseudo code python)

def loadData():
    if (#dict exists on disk):
        d = shelve.open(name)
        return d
    else:
        d = shelve.open(name, writeback=True)
        #access DB and write data to dict
        # d[key] = value 
        # or for mutable values
        # oldValue = d[key]
        # newValue = f(oldValue)
        # d[key] = newValue 
        d.close()
        d = shelve.open(name, writeback=True)
        return d

J'ai deux ou trois questions,

1) Ai-je vraiment besoin de l'écriture différée = True? Que faut-il faire?

2) Je reçois encore une exception mémoire saturée, puisque je n'exerce aucun contrôle sur le moment où les données sont en cours d'écriture sur le disque. Comment je fais ça? J'ai essayé de faire une synchronisation () toutes les quelques itérations, mais cela n'a pas aidé non plus.

Merci!

Était-ce utile?

La solution

writeback=True oblige l'étagère à garder en mémoire tout élément jamais tiré par les cheveux, et les écrire en arrière quand le plateau est fermé. Ainsi, il consomme beaucoup plus de mémoire et ralentit la fermeture.

L'avantage du paramètre est que, avec elle, vous ne pas besoin du code crispé vous montrez dans vos commentaires pour les articles mutables dont mutator est une méthode - juste

shelf['foobar'].append(23)

œuvres (si shelf a été ouvert avec writeback activé), en supposant que l'élément à 'foobar' clé est une liste bien sûr, alors qu'il serait silencieusement une non-opération (en laissant l'élément sur le disque inchangé) si shelf a été ouvert sans writeback - - dans ce dernier cas, vous avez réellement besoin de code

thelist = shelf['foobar']
thelist.append(23)
shekf['foobar'] = thelist

dans l'esprit de votre commentaire -. Qui est stylistiquement un peu une vraie corvée

Cependant, puisque vous sont ayant des problèmes de mémoire, je vous recommande vraiment pas en utilisant cette option douteuse writeback. Je pense que je peux l'appeler « douteux » depuis que je suis celui qui propose et première mise en œuvre, mais c'était il y a plusieurs années, et je me suis surtout repenti de le faire - il Generales plus de confusion (comme vos preuves Q) que permet élégance et praticité dans le code en mouvement écrit à l'origine pour travailler avec dicts (qui utiliserait le premier idiome, pas le second, et ont donc besoin de réécriture pour être utilisable avec des étagères sans retraçage). Eh bien, désolé, ce ne semble une bonne idée à l'époque.

Autres conseils

Utilisation du module sqlite3 est probablement votre meilleur choix ici. Vous pourriez être en mesure d'utiliser SQLite entièrement en mémoire de toute façon depuis son empreinte mémoire est peut-être un peu plus petit que d'utiliser des objets python de toute façon. Il est généralement un meilleur choix que d'utiliser shelve de toute façon; shelve utilise pickle en dessous, ce qui est rarement ce que vous voulez.

L'enfer, vous pouvez simplement convertir la totalité de votre base de données existante à une base de données SQLite. SQLite est agréable et rapide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top