2017-03-10 4 views
1

Ich habe mit Python Daten aus einer Postgres-Datenbank abgerufen. Und es braucht viel Speicher.Übermäßige Speichernutzung beim Abrufen von Daten aus einer Postgres-Datenbank

memory usage

Die folgende Funktion ist die einzige Funktion, die ich leite, und es wird eine übermäßige Menge an Speicher Aufnahme: Wie weiter unten sehen. Ich verwende fetchmany() und Daten in kleinen Stücken abzurufen. Ich habe auch versucht, den Cursor iterativ zu verwenden. Alle diese Methoden enden jedoch mit wirklich übermäßiger Speicherbelegung. Hat jemand eine Ahnung, warum das passiert? Gibt es etwas, das ich am Postgres-Ende einstellen muss, um dieses Problem zu beheben?

def checkMultipleLine(dbName): 
    ''' 
    Checks for rows that contain data spanning multiple lines 

    This is the most basic of checks. If a aprticular row has 
    data that spans multiple lines, then that particular row 
    is corrupt. For dealing with these rows we must first find 
    out whether there are places in the database that contains 
    data that spans multiple lines. 
    ''' 

    logger = logging.getLogger('mindLinc.checkSchema.checkMultipleLines') 
    logger.info('Finding rows that span multiple lines') 

    schema = findTables(dbName) 

    results = [] 
    for t in tqdm(sorted(schema.keys())): 

     conn = psycopg2.connect("dbname='%s' user='postgres' host='localhost'"%dbName) 
     cur = conn.cursor() 
     cur.execute('select * from %s'%t) 
     n = 0 
     N = 0 
     while True: 
      css = cur.fetchmany(1000) 
      if css == []: break 
      for cs in css: 
       N += 1 
       if any(['\n' in c for c in cs if type(c)==str]): 
        n += 1 
     cur.close() 
     conn.close() 

     tqdm.write('[%40s] -> [%5d][%10d][%.4e]'%(t, n, N, n/(N+1.0))) 
     results.append({ 
      'tableName': t, 
      'totalRows': N, 
      'badRows' : n, 
     }) 


    logger.info('Finished checking for multiple lines') 

    results = pd.DataFrame(results)[['tableName', 'badRows', 'totalRows']] 
    print results 
    results.to_csv('error_MultipleLine[%s].csv'%(dbName), index=False) 

    return results 
+0

Wie haben Sie es geschafft, mehr als einen Python-Prozess zu erhalten? Tut psycopg2 das? – hurturk

+0

Ich vermute es ist psycopy das tun. Ich habe mit meinem Code nichts Besonderes gemacht, um neue Prozesse einzuleiten .... – ssm

+0

Ich habe eine Option gefunden, den Puffer auf folgendes zu beschränken [http://stackoverflow.com/a/28343332/1233686], habe hast du das versucht? – hurturk

Antwort

2

psycopg2 unterstützt server-side cursors für große Abfragen in diesem answer wie angegeben verwendet werden. Hier ist, wie es mit clientseitige Puffereinstellung zu verwenden ist:

cur = conn.cursor('cursor-name') 
cur.itersize = 10000 # records to buffer on a client 

Das sollte den Speicherbedarf reduzieren.

Verwandte Themen