web-dev-qa-db-fra.com

Python db-api: fetchone vs fetchmany vs fetchall

Je viens d'avoir une discussion aujourd'hui avec quelques collègues sur detch-fi fetchone vs fetchmany vs fetchall de python.

Je suis sûr que le cas d'utilisation de chacun d'entre eux dépend de l'implémentation de la db-api que j'utilise, mais en général quels sont les cas d'utilisation de fetchone vs fetchmany vs fetchall?

En d'autres termes, les équivalents suivants sont-ils? ou y en a-t-il un qui est préféré aux autres? et si oui dans quelles situations?

cursor.execute("SELECT id, name FROM `table`")
for i in xrange(cursor.rowcount):
    id, name = cursor.fetchone()
    print id, name


cursor.execute("SELECT id, name FROM `table`")
result = cursor.fetchmany()
while result:
    for id, name in result:
        print id, name
    result = cursor.fetchmany()


cursor.execute("SELECT id, name FROM `table`")
for id, name in cursor.fetchall():
    print id, name
60
Alex Q

Je pense que cela dépend en effet de l'implémentation, mais vous pouvez vous faire une idée des différences en consultant les sources MySQLdb. Selon les options, mysqldb fetch * conserve l'ensemble actuel de lignes en mémoire ou côté serveur, donc fetchmany vs fetchone a une certaine flexibilité ici pour savoir quoi garder en mémoire (python) et quoi garder côté serveur db.

PEP 249 ne donne pas beaucoup de détails, donc je suppose que c'est pour optimiser les choses en fonction de la base de données alors que la sémantique exacte est définie par l'implémentation.

14
David Cournapeau

Ce sont spécifiques à l'implémentation.

  • fetchall

Obtiendra tous les résultats du tableau. Cela fonctionnera mieux lorsque la taille de la table est petite. Si la taille de la table est plus grande, fetchall échouera dans ces cas.

Va utiliser la plupart de la mémoire.

Des problèmes peuvent survenir si les requêtes sont effectuées sur le réseau.

  • fetchmany

fetchmany n'obtiendra que le nombre requis de résultats. Vous pouvez produire les résultats et le processus. Extrait simple d'implémentation de fetchmany.

   while True:
    results = cursor.fetchmany(arraysize)
    if not results:
        break
    for result in results:
        yield result
7
Niranjan Sagar

fetchone ()

Récupérez la ligne suivante d'un jeu de résultats de requête, en renvoyant un seul Tuple ou None lorsque plus aucune donnée n'est disponible:

>>> cur.execute("SELECT * FROM test WHERE id = %s", (3,))
>>> cur.fetchone()

(3, 42, 'bar')

Une erreur ProgrammingError est déclenchée si l'appel précédent pour exécuter * () n'a produit aucun jeu de résultats ou si aucun appel n'a encore été émis.

fetchmany ([size = cursor.arraysize])

Récupère le prochain ensemble de lignes d'un résultat de requête, en renvoyant une liste de tuples. Une liste vide est renvoyée lorsqu'aucune ligne n'est disponible.

Le nombre de lignes à récupérer par appel est spécifié par le paramètre. S'il n'est pas donné, la taille du tableau du curseur détermine le nombre de lignes à récupérer. La méthode doit essayer de récupérer autant de lignes que l'indique le paramètre de taille. Si cela n'est pas possible car le nombre de lignes spécifié n'est pas disponible, moins de lignes peuvent être renvoyées:

>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchmany(2)
[(1, 100, "abc'def"), (2, None, 'dada')]
>>> cur.fetchmany(2)
[(3, 42, 'bar')]
>>> cur.fetchmany(2)
[]

Une erreur ProgrammingError est déclenchée si l'appel précédent pour exécuter * () n'a produit aucun jeu de résultats ou si aucun appel n'a encore été émis.

Notez qu'il existe des considérations de performances impliquées avec le paramètre de taille. Pour des performances optimales, il est généralement préférable d'utiliser l'attribut arraysize. Si le paramètre de taille est utilisé, il est préférable qu'il conserve la même valeur d'un appel fetchmany () au suivant.

Élément de liste

fetchall ()

Récupère toutes les lignes (restantes) d'un résultat de requête, en les renvoyant sous forme de liste de tuples. Une liste vide est retournée s'il n'y a plus d'enregistrement à récupérer.

>>> cur.execute("SELECT * FROM test;")
>>> cur.fetchall()
[(1, 100, "abc'def"), (2, None, 'dada'), (3, 42, 'bar')]

Une erreur ProgrammingError est déclenchée si l'appel précédent pour exécuter * () n'a produit aucun jeu de résultats ou si aucun appel n'a encore été émis.

4
shreesh katti