Meilleure façon de parcourir toutes les lignes d'une table DB
J'écris souvent peu de scripts Python pour itérer sur toutes les lignes de la base de données de la table.
Par exemple l'envoi de tous à tous les abonnés un e-mail.
Je fais comme ça
conn = MySQLdb.connect(host = hst, user = usr, passwd = pw, db = db)
cursor = conn.cursor()
subscribers = cursor.execute("SELECT * FROM tbl_subscriber;")
for subscriber in subscribers:
...
conn.close()
Je me demande si il y a une meilleure façon de faire de cette cause, il est possible que mon code charge des milliers de lignes dans la mémoire.
J'ai pensé qu'il pourrait faire mieux avec LIMIT
.
Peut-être quelque chose comme ça:
"SELECT * FROM tbl_subscriber LIMIT %d,%d;" % (actualLimit,steps)
Quel est le meilleur moyen de le faire?
Comment le feriez-vous?
source d'informationauteur OemerA
Vous devez vous connecter pour publier un commentaire.
sauf si vous avez les Gouttes de là, des milliers de lignes ne devrait pas être un problème. Savez-vous qu'il est?
Aussi, pourquoi apporter la honte sur vous-même et toute votre famille en faisant quelque chose comme
lorsque le curseur se faire le changement pour vous dans une manière qui évite les injection SQL?
Vous n'avez pas à modifier la requête, vous pouvez utiliser le fetchmany méthode de curseurs. Voici comment je le fais :
De cette façon, vous pouvez "SELECT * from tbl_subscriber;" mais vous ne chercher certains à la fois.
La plupart des connecteurs MySQL basé sur libmysqlclient stockera tous les résultats dans la mémoire du client par défaut pour des raisons de performances (avec l'hypothèse que vous ne serez pas en lisant de grands jeux de résultats).
Lorsque vous avez besoin de lire un grand résultat dans MySQLdb vous pouvez utiliser un SSCursor pour éviter de mise en mémoire tampon entière de grands jeux de résultats.
http://mysql-python.sourceforge.net/MySQLdb.html#using-and-extending
Ce n'introduisent des complications que vous devez être prudent de. Si vous ne lisez pas tous les résultats à partir du curseur, une deuxième requête génère une ProgrammingError:
Cela signifie que vous devez toujours tout lire à partir du curseur (et potentiellement de plusieurs jeux de résultats) avant la délivrance d'un autre - MySQLdb de ne pas le faire pour vous.
Tout d'abord peut-être que vous n'avez pas besoin Select * from...
c'est peut-être assez pour vous juste pour obtenir des trucs comme: "SELECT email from..."
qui permettraient de diminuer le montant de l'utilisation de la mémoire de toute façon:)
Avez-vous des réels problèmes de mémoire? Lors de l'itération sur un curseur, les résultats sont extraites une à une (DB-API de mise en œuvre peut décider de prefetch résultats, mais alors qu'il pourrait offrir une fonction pour définir le nombre de prefetched résultats).