2015-09-17 16 views
11

Chciałbym zrobić ten proces w partiach, ze względu na objętość.Pobieranie danych z MySQL w partiach za pomocą Pythona

Oto mój kod:

getconn = conexiones() 
con = getconn.mysqlDWconnect() 
with con: 
    cur = con.cursor(mdb.cursors.DictCursor) 
    cur.execute("SELECT id, date, product_id, sales FROM sales") 
    rows = cur.fetchall() 

Jak mogę zaimplementować indeksu, aby pobrać dane w partii?

Odpowiedz

18

Pierwszy punkt: pyton db-api.cursor jest iterator, więc chyba naprawdę trzeba załadować całą partię w pamięci na raz, można po prostu zacząć przy użyciu tej funkcji, czyli zamiast:

cursor.execute("SELECT * FROM mytable") 
rows = cursor.fetchall() 
for row in rows: 
    do_something_with(row) 

może po prostu:

cursor.execute("SELECT * FROM mytable") 
for row in cursor: 
    do_something_with(row) 

Następnie, jeśli realizacja Twojego łącznika db nadal nie czyni właściwego wykorzystania tej funkcji, to będzie czas, aby dodać LIMIT i OFFSET do mieszanki:

cursor.execute("SELECT count(*) FROM mytable") 
count = cursor.fetchone()[0] 
batch_size = 42 # whatever 

for offset in xrange(0, count, batch_size): 
    cursor.execute(
     "SELECT * FROM mytable LIMIT %s OFFSET %s", 
     (batch_size, offset)) 
    for row in cursor: 
     do_something_with(row) 
+0

Twoje rozwiązanie jest o wiele czystsze niż moje! –

4

Można użyć

SELECT id, date, product_id, sales FROM sales LIMIT X OFFSET Y; 

gdzie X jest wielkość partii trzeba i Y jest prąd przesunięcia (czasy X liczba obecnych iteracji dla przykładu)

0

Aby rozwinąć na odpowiedź akalikin, w ty może użyć krokowej iteracji, aby podzielić zapytanie na porcje, a następnie użyć LIMIT i OFFSET do wykonania zapytania.

cur = con.cursor(mdb.cursors.DictCursor) 
cur.execute("SELECT COUNT(*) FROM sales") 

for i in range(0,cur.fetchall(),5): 
    cur2 = con.cursor(mdb.cursors.DictCursor) 
    cur2.execute("SELECT id, date, product_id, sales FROM sales LIMIT %s OFFSET %s" %(5,i)) 
    rows = cur2.fetchall() 
    print rows 
0

Dziękuję, oto jak zaimplementować go ze swoimi sugestiami:

control = True 
index = 0 
while control==True: 
    getconn = conexiones() 
    con = getconn.mysqlDWconnect() 
    with con: 
     cur = con.cursor(mdb.cursors.DictCursor) 
     query = "SELECT id, date, product_id, sales FROM sales limit 10 OFFSET " + str(10 * (index)) 
     cur.execute(query) 
     rows = cur.fetchall() 
     index = index+1   
     if len(rows)== 0: 
      control=False 
    for row in rows: 
     dataset.append(row) 
+1

Widzę, że zbieracie wiersze w obiekcie, który wydaje się być obiektem "list" lub "list", który to rodzaj pokonuje cały punkt wsadowy i iterację kursora bezpośredniego, tj. Unikając załadowania całego półkola w pamięć ... Czy mogę zapytać, jak używasz tego obiektu 'dataset'? Tutaj może być o wiele lepsze rozwiązanie, Python ma silne poparcie dla leniwej oceny. –

+0

Potrzebuję pobrać zbiór danych 18M wierszy, po nim muszę wyczyścić niektóre odniesienia, które nie są zainteresowane (podzbiór) i scalić go z innym. –

+0

Czy naprawdę potrzebujesz do tego całego zestawu danych w pamięci? Podczas pracy nad "olbrzymimi" zbiorami danych, kanoniczny wzór polega na wykorzystaniu rozwiązania "strumień/proces/zapis". –

Powiązane problemy