web-dev-qa-db-fra.com

Pourquoi avez-vous besoin de créer un curseur lorsque vous interrogez une base de données sqlite?

Je suis complètement nouveau dans le module sqlite3 de Python (et SQL en général d'ailleurs), et cela me stoppe complètement. Le manque abondant de descriptions d'objets cursor (plutôt de leur nécessité) semble également étrange. 

Cet extrait de code est le moyen privilégié de procéder:

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

Celui-ci ne l'est pas, même s'il fonctionne aussi bien et sans la (variable apparemment inutile) cursor:

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

Quelqu'un peut-il me dire pourquoi j'ai besoin d'une cursor?
Cela semble juste comme une surcharge inutile. Pour chaque méthode de mon script qui accède à une base de données, je suis supposée créer et détruire une cursor?
Pourquoi ne pas simplement utiliser l'objet connection?

96
Jack Bauer

Juste une abstraction mal appliquée, il me semble. Un curseur de base de données est une abstraction, destinée à la traversée de fichiers.

De article Wikipedia sur le sujet :

En informatique et technologie, un curseur de base de données est un contrôle structure qui permet la traversée des enregistrements d'une base de données . Les curseurs facilitent le traitement ultérieur en conjonction avec le parcours, comme l'extraction, l'ajout et la suppression d'une base de données enregistrements. Le curseur de base de données caractéristique de la traversée crée des curseurs s'apparente au concept de langage de programmation de l'itérateur.

Et:

Les curseurs ne peuvent pas uniquement être utilisés pour extraire des données du SGBD dans un fichier mais aussi pour identifier une ligne dans une table à mettre à jour ou supprimé. La norme SQL: 2003 définit la mise à jour positionnée et positionné supprimer les instructions SQL à cet effet. De telles déclarations font pas utiliser une clause WHERE régulière avec des prédicats. Au lieu de cela, un curseur identifie la ligne. Le curseur doit être ouvert et déjà positionné sur une ligne au moyen de l'instruction FETCH.

Si vous vérifiez les docs sur le module sqlite Python , vous verrez qu'un module python cursor est nécessaire même pour une instruction CREATE TABLE; il est donc utilisé dans les cas où un simple objet connection devrait suffire. - comme l'a souligné correctement l'OP. Une telle abstraction est différente de ce que les gens comprennent comme un curseur de base de données et, partant, de la confusion/frustration de la part des utilisateurs. Indépendamment de l'efficacité, c'est juste une surcharge conceptuelle. Ce serait bien s'il était indiqué dans la documentation que le module python cursor diffère un peu de la valeur d'un curseur dans SQL et les bases de données.

49
Basel Shishani

Vous avez besoin d'un objet curseur pour récupérer les résultats. Votre exemple fonctionne parce que c'est un INSERT et que vous n'essayez donc pas de récupérer des lignes, mais si vous regardez le sqlite3 docs , vous remarquerez qu'il n'y a pas de méthodes .fetchXXXX sur les objets de connexion. Ainsi, si vous tentiez de faire un SELECT sans curseur, vous n’auriez aucun moyen d’obtenir les données résultantes.

Les objets Cursor vous permettent de savoir quel jeu de résultats correspond à quel jeu, puisqu’il est possible d’exécuter plusieurs requêtes avant d’avoir récupéré les résultats de la première.

31
Amber

Selon le document officiel -docsconnection.execute() est un raccourci non standard qui crée un objet curseur intermédiaire:

Connection.execute
C’est un raccourci non standard qui crée un objet curseur en appelant la méthode cursor (), appelle la méthode execute () du curseur avec les paramètres donnés et renvoie le curseur.

27
user

12.6.8. Utilisation de sqlite3 efficace ly

12.6.8.1. Utiliser les méthodes raccourci

En utilisant les méthodes non standardexecute(), executemany() et executescript() de l'objet Connection, votre code peut être écrit plus concis _ly car vous n'avez pas à créer le (souvent superflu) Objets de curseur explicitement. Au lieu de cela, les objets Cursor sont créés implicitement et ces méthodes de raccourci renvoient les objets curseur. De cette façon, vous pouvez exécuter une instruction SELECT et la parcourir directement en utilisant un seul appel sur l'objet Connection.

( sqlite3 documentation ; l'emphase est ma mine.)

Pourquoi ne pas simplement utiliser l'objet de connexion?

Parce que ces méthodes de l’objet de connexion sont non standard , c’est-à-dire qu’elles ne font pas partie de Spécification API de base de données Python v2.0 (PEP 249).

Tant que vous utilisez les méthodes standard de l'objet Cursor, vous pouvez être sûr que si vous passez à une autre implémentation de base de données conforme à la spécification ci-dessus, votre code sera entièrement portable. Peut-être aurez-vous seulement besoin de changer la ligne import.

Mais si vous utilisez le connection.execute, il est possible que le changement ne soit pas aussi simple. C'est la raison principale pour laquelle vous voudrez peut-être utiliser cursor.execute à la place.

Toutefois, si vous êtes certain de ne pas basculer, je dirais que le raccourci connection.execute est tout à fait correct et que vous êtes "efficace".

11
AXO

Cela nous donne la possibilité de disposer de plusieurs environnements de travail distincts via la même connexion à la base de données.

0
Python Learner