2009-07-21 8 views
2

Courant J'utilise SQLite (w/SQLAlchemy) pour stocker environ 5000 objets dict. Chaque objet dict correspond à une entrée dans PyPI avec des clés - (nom, version, résumé .. parfois 'description' peut être aussi grand que la documentation du projet).Stockage dict rapide et indexable pour Python

L'écriture de ces entrées (à partir de JSON) sur le disque (format SQLite) prend plusieurs secondes et semble lente.

L'écriture est aussi fréquente qu'une fois par jour, mais la lecture/recherche d'une entrée particulière basée sur une touche (généralement le nom ou la description) est très souvent effectuée.

Tout comme apt-get.

Y a-t-il une bibliothèque de stockage à utiliser avec Python qui convienne mieux à mes besoins que SQLite?

+1

Pourquoi recréer la base de données à partir de JSON tous les jours? À quoi ressemble votre code d'insertion? Si vous insérez beaucoup de données, vous pouvez vouloir éviter la couche ORM de SQLAlchemy et utiliser des expressions d'insertion: http://www.sqlalchemy.org/docs/05/sqlexpression.html#insert-expressions –

Répondre

2

Avez-vous mis des indices sur le nom et la description? La recherche sur 5000 entrées indexées devrait être essentiellement instantanée (bien sûr, les ORM vous compliqueront la vie, comme ils le font habituellement [même relativement bons comme SQLAlchemy, mais essayez "raw sqlite" et il devrait absolument voler). Ecrire uniquement les entrées mises à jour (encore une fois avec SQL réel) devrait également être fondamentalement instantané - idéalement, une seule instruction de mise à jour devrait le faire, mais même un millier ne devrait pas poser de problème, assurez-vous de désactiver l'autocommit au début de la boucle (et si vous voulez le réactiver plus tard).

+0

En fait, il écrit ces 5000 entrées qui sont lentes. Et, essentiellement, je dois tous les écrire, disons, tous les jours. Pensez à "apt-get update" avec un index de paquet mis à jour prêt à être téléchargé. –

+0

@srid, pouvez-vous donner les instructions détaillées CREATE TABLE? On dirait que cela doit être particulier - dans mes expériences, il faut plus de temps pour obtenir des informations de pypi via xmlrpclib que pour le mettre à jour dans sqlite (bien sûr, vous ne modifiez que SQLite ce qui a changé: pourquoi devriez-vous réécrire entrées?!). –

+1

il y a un commentaire dans la documentation de sqlite qui indique que chaque 'INSERT' est une transaction par défaut, prenant au minimum 2 rotations de disque à compléter (écrire et vérifier). Si vous encapsulez tout le travail dans un bloc 'BEGIN..COMMIT', vous éviterez cela et obtiendrez un débit beaucoup plus rapide - http://www.sqlite.org/atomiccommit.html & http://www.sqlite.org/speed .html – warren

1

Il est peut-être trop lourd pour votre application, mais vous devez vérifier les bases de données sans schéma/document. Personnellement, je suis un fan de couchdb. Fondamentalement, plutôt que de stocker des enregistrements comme des lignes dans une table, quelque chose comme couchdb stocke des paires clé-valeur, puis (dans le cas de couchdb) vous écrivez des vues en javascript pour éliminer les données dont vous avez besoin. Ces bases de données sont généralement plus faciles à mettre à l'échelle que les bases de données relationnelles, et dans votre cas, elles peuvent être beaucoup plus rapides, car vous n'avez pas besoin de forcer vos données dans une forme qui s'intégrera dans une base de données relationnelle. D'un autre côté, cela signifie qu'un autre service est en cours d'exécution.

+0

Oui, couchdb est une overkill pour une application de ligne de commande essentiellement autonome. :-) –

+0

Alors que CouchDB n'est pas mon magasin de données préféré, je ne pense pas que ce soit excessif - il semble être une option préférée pour les systèmes autonomes ou intégrés (par exemple http://www.couchone.com/android) –

+0

Mongodb , d'autre part, a des extensions JSON compilées en C et un datastore non transactionnel par défaut à très haute vitesse. Mais il préfère exécuter un processus séparé en tant qu'utilisateur spécial, ce qui entraîne une charge de configuration plus importante. –

0

Étant donné le nombre approximatif d'objets indiqués (environ 5 000), SQLite n'est probablement pas le problème de la vitesse. Ce sont les mesures intermédiaires; par exemple JSON ou une utilisation potentiellement non optimale de SQLAlChemy.

Try this out (assez rapide, même pour des millions d'objets): Module y_serial.py :: entrepôt des objets Python avec SQLite

« sérialisation + :: persistence en quelques lignes de code, compriment et annoter des objets Python dans SQLite, puis plus tard, les récupérer chronologiquement par mots-clés sans aucun SQL. "Module" standard le plus utile pour une base de données pour stocker des données sans schéma. "

http://yserial.sourceforge.net

La recherche yserial sur vos clés se fait en utilisant l'expression régulière (« regex ») le code du côté SQLite, pas Python, donc il y a une autre amélioration importante de la vitesse.

Dites-nous comment cela fonctionne.

0

Je résous un problème très similaire pour moi maintenant, en utilisant Nucular, ce qui pourrait répondre à vos besoins. C'est un stockage basé sur le système de fichiers et semble très rapide en effet. (Il est livré avec un exemple d'application qui indexes the whole python source tree) Il est concurrentiel, ne nécessite aucune bibliothèque externe et est pur python.Il recherche rapidement et possède une puissante recherche en texte intégral, indexation et ainsi de suite - une sorte de magasin python-dict spécialisé, en cours de traitement, à la manière des Couchdb et mongodb à la mode, mais beaucoup plus léger. Il a cependant des limites: il ne peut stocker ou interroger les dictionnaires imbriqués, de sorte que tous les types JSON ne peuvent pas y être stockés. De plus, bien que sa recherche de texte soit puissante, ses requêtes numériques sont faibles et non indexées. Néanmoins, c'est peut-être précisément ce que vous recherchez.