[Python] sqlite executemany ed utilizzo/saturazione della memoria...

Pietro Zambelli peter.zamb a gmail.com
Gio 31 Ott 2013 17:45:13 CET


Ciao a tutti,

sto cercando di popolare una tabella con alcune statistiche, il db è sqlite...
solo che l'operazione satura velocemente la memoria della macchina e non riesco a capire perché. Nel giro di pochi minuti mi satura i 24G + 8G tra memoria fisica e swap...

Ho da inserire ~2M di righe ogni riga è composta da 9 valori tre int e il resto double...

Ho definito una funzione "area_stats" che prende un oggetto e mi restituisce una lista con i 9 valori che vanno inseriti nel db.


def area_stats(cat, vect):
    # instanzio l'oggetto area e mi estraggo dei valori
    # elimino l'instanza con del(area)
    return [0, ] * 9

def istats(icats, vect, done):
    for arid, cat in icats:
        if cat > 0 and cat not in done:
            yield area_stats(cat, vect)
            done.add(cat)

def compute_and_insert(icats, vect, done):
    print('.', end='')
    vect.table.insert(istats(icats, vect, done), many=True)
    vect.table.conn.commit()


Per cercare di minimizzare il problema ho spezzato la lista delle aree da analizzare in modo che sia divida in pezzi con soli 10k righe "icats".


Il metodo che viene chiamato per inserire i dati nella tabella è così definito:


    def insert(self, values, many=False):
        """Insert a new row"""
        cur = self.conn.cursor()
        if many:
            return cur.executemany(self.columns.insert_str, values)
        return cur.execute(self.columns.insert_str, values)

con self.columns.insert_str che è: 'INSERT = "INSERT INTO {tname} VALUES (?,?,?,?,?,?,?,?,?)"'


Analizzando il consumo di memoria da parte dello script con memory_profiler ottengo:


Line # Mem usage  Increment   Line Contents
================================================
101   2828.7 MiB    0.0 MiB   @profile
102                           def icompute_and_insert(icats, vect, done):
103   2828.7 MiB    0.0 MiB       print('.', end='')
104   2941.1 MiB  112.4 MiB       vect.table.insert(istats(icats, vect, done), many=True)
105   2941.1 MiB    0.0 MiB       vect.table.conn.commit()


il problema sembra dovuto al fatto che executemany non libera la memoria, qualcuno ha idea perché questo succede e di come si possa risolvere?


Grazie per l'aiuto.

Pietro


-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20131031/9272da0a/attachment.html>


Maggiori informazioni sulla lista Python