2009-11-27 20 views
27

Büyük bir sonuç kümesiyle uğraşmalıyım (bazen yüzlerce satır olabilir, bazen daha fazla).
Maalesef hepsi bir kerede (başlangıçta) alınmaları gerekiyor.MySQLDB SScursor nasıl kullanılır?

Bunu mümkün olduğunca az bellek kullanarak yapmaya çalışıyorum.
SO baktığımda, aradığım şey SSCursor kullanıyor olabilir, ancak tam olarak bunları nasıl kullanacağımı gerçekten bilmiyorum.

Bir temel imleç veya bir SScursor'dan aynı şekilde (bellek kullanımı açısından) bir fetchall() mu yapıyorsunuz?
Sscursor satırlarımdan birini tek tek (ya da birkaçını birkaç) aktarabilir miyim? Evet ise
bunu yapmanın en iyi yolu nedir?

cevap

28

Otto Allmendinger yanıt ile anlaşma değilim, ama açık Denis Otkidach yorumuna yapmak, burada Otto'nun getirme() fonksiyonunu kullanmadan sonuçları adımlayabilirsiniz nasıl: Alternatif

import MySQLdb.cursors 
connection=MySQLdb.connect(
    host="thehost",user="theuser", 
    passwd="thepassword",db="thedb", 
    cursorclass = MySQLdb.cursors.SSCursor) 
cursor=connection.cursor() 
cursor.execute(query) 
for row in cursor: 
    print(row) 
+0

Sanırım aradığım şey buydu, teşekkürler – Sylvain

+0

Bu satır tek tek mi getiriyor? Değilse, bu sefer kaç tane satır alır. 37 milyondan fazla kaydı olan bir db var. Kayıtları tek tek okumalı ve bir dosyaya koymalıyım (bazı ek şeylerle basit bir dökümü olamaz). Bu bir şekilde paralel olarak yapılabilir. Mesela, 10000 satır yazıyor ve yazarken bazı satırlar getiriliyor ve bu şekilde devam ediyor .. – Sohaib

+0

@Sohaib: Her seferinde bir satır getiriyor. Sorununuz CPU'ya bağlıysa, birden çok DB okuyucuyu ayarlamak için çoklu işlem (Python2/3) veya concurrent.futures (Python3'te) kullanabilirsiniz, ancak dosyaya yalnızca bir yazar kullanmalısınız, aksi halde kayıtlar bozuk. [Sorununuz IO-bağlıysa] (http://eli.thegreenplace.net/2012/01/16/python-parallelizing-cpu-bound-tasks-with-multiprocessing/) - eğer dosyaya yazıyorsanız darboğaz - daha sonra birden fazla okuyucu ayarlayarak işi hızlandırmaz. – unutbu

9

Büyük sonuç kümeleri alırken kesinlikle SSCursor kullanın. Benzer bir sorun yaşadığımda benim için büyük bir fark yarattı. Bu gibi kullanabilirsiniz:

import MySQLdb 
import MySQLdb.cursors 

connection = MySQLdb.connect(
     host=host, port=port, user=username, passwd=password, db=database, 
     cursorclass=MySQLdb.cursors.SSCursor) # put the cursorclass here 
cursor = connection.cursor() 

Şimdi cursor.execute() ile sorguyu yürütmek ve bir yineleyici olarak imleci kullanabilirsiniz.

Edit: gereksiz evegrown yineleyici kaldırıldı, teşekkürler Denis!

+3

İmleç nesnesi yinelenebilir, bu yüzden üzerinde jeneratör yazılmasına gerek yoktur. Aksi takdirde 'iter (cursor.fetchone, None)' kullanabilirsiniz. –

0

kullanabileceğiniz Bağlantı nesnesinin dışındaki SSCursor (bağlantıyı önceden tanımladığınızda ve tüm bağlantıların SSCursor'un bir cursorclass olarak kullanılmasını istemediğinizde oldukça önemlidir).

import MySQLdb 
from MySQLdb.cursors import SSCursor # or you can use SSDictCursor 

connection = MySQLdb.connect(
     host=host, port=port, user=username, passwd=password, db=database) 
cursor = SSCursor(connection) 
cursor.execute(query) 
for row in cursor: 
    print(row) 
İlgili konular