2010-10-13 2 views
1

J'ai décidé que je ne suis pas friand de l'archivage automatique et le renommage fourni par Mendeley, mais j'ai trouvé qu'il garde la trace de tout dans une base de données sqlite que je peux facilement lire et modifier à partir de Python. Ma question est, si je vais itérer sur les lignes d'une table contenant des chemins de fichier et des hachages qui servent d'identificateurs utilisés ailleurs dans la base de données, quel est le modèle approprié à utiliser pour mettre à jour les chemins au fur et à mesure que je me déplace, je vérifie si le fichier doit être renommé, puis je veux mettre à jour la ligne dans la base de données lorsque je déplace le fichier.Examiner puis mettre à jour les lignes dans sqlite avec Python

J'ai commencé à assembler un peu de Python pour cela, mais il me semble que je devrais probablement faire une requête à l'avance pour obtenir toutes les lignes que je vais parcourir, et ensuite faire des instructions REPLACE ou UPDATE pour les fichiers, j'ai décidé de déménager.

Je ne suis pas familier avec les internes du module sqlite3, mais je suppose que ce serait une mauvaise idée de faire REPLACE/UPDATEs tout en itérant sur le curseur utilisé pour la sélection d'origine.

Existe-t-il une autre façon de faire cela qui ne nécessite pas de revenir avec REPLACE/UPDATEs? J'ai besoin de faire des requêtes à partir d'autres tables, en utilisant le hachage du fichier pour obtenir d'autres métadonnées afin de construire le renommer.

Répondre

2

Je ne pense pas qu'il existe un moyen de modifier les lignes de la table autrement que via SQL - UPDATE, ou INSERT OR REPLACE. (Il est tentant de penser que l'objet sqlite3.Row peut autoriser l'assignation, et réécrire sur la ligne qu'il représente, mais non.)

Pour faire des UPDATE (via un 2ème curseur) alors qu'il y a un curseur original SELECT - vous demandez si c'est une mauvaise idée - je ne sais pas si vous vous inquiétez de l'exactitude ou de la performance (correction: le curseur est confus et n'itère pas toutes les lignes qu'il devrait exactement une fois; le curseur itère-t-il toutes les lignes qu'il devrait exactement une fois mais il y a un tas de requêtes supplémentaires chères)?

WRT correct, cela semble fonctionner correctement - je viens de faire un test rapide où j'ai créé deux curseurs, c1 et c2, puis sur c1 exécuté une commande SELECT, puis sur c2 exécuté une commande UPDATE affectant les mêmes lignes, alors regardé le résultat de c1.fetchall(). Il contenait toujours toutes les bonnes lignes, bien que les données de la première rangée étaient obsolètes (probablement récupérées avec la requête initiale) et les données dans les dernières lignes étaient mises à jour (probablement récupérées uniquement avec le fetchall après la mise à jour). (De plus, si la mise à jour de c2 affecte les enregistrements qui seront retournés par le SELECT sur c1, ces enregistrements ne seront plus récupérés, mais évidemment tout ce qui a déjà été récupéré a déjà été récupéré, et le curseur.execute() semble pour récupérer le premier enregistrement immédiatement, donc en utilisant le même ordre de commande comme ci-dessus et avec une commande UPDATE qui ferait que le SELECT original ne trouve rien, le dernier c1.fetchall() renvoie toujours un enregistrement.)

Je ne sais pas - à partir du paragraphe précédent, il me semble qu'il doit répéter la requête, ce qui peut ou peut ne pas être coûteux en fonction de la requête. (Peut-être ne le répète-t-il pas littéralement, peut-être que ce travail est différé jusqu'à l'extraction réelle.)

Petite histoire: Je ne pense pas qu'il existe une autre façon de le faire sans UPDATE ou REPLACE, et je pense que ça marchera ok pour faire ces UPDATEs même en itérant sur le curseur d'origine.

+0

Merci pour les notes à ce sujet. Je m'inquiétais plus de la correction que de la performance. Je suppose que l'on aurait besoin d'utiliser un plus haut niveau d'abstraction, comme un ORM pour pouvoir faire ce que je voulais initialement, au moins du point de vue du code Python.Au final, j'ai remarqué pour Mendeley au moins que je n'avais pas vraiment besoin de mettre à jour les noms de fichiers dans la base de données car si on renomme le fichier et demande à Mendeley de regarder le dossier le contenant, il mettra à jour les chemins fichiers avec le même hachage que le chemin de fichier précédent. –

Questions connexes