MySql FetchMany Проблемы с памятью

Я перемещаю данные из Mysql в Postgres, и мой код, как показано ниже -

import os, re, time, codecs, glob, sqlite3
from StringIO import StringIO
import psycopg2, MySQLdb, datetime, decimal
from datetime  import date
import gc

tables = (['table1' , 27],)
conn = psycopg2.connect("dbname='xxx' user='xxx' host='localhost' password='xxx' ")
curpost = conn.cursor()
db = MySQLdb.connect(host="127.0.0.1", user="root", passwd="root" , unix_socket='/var/mysql/mysql.sock', port=3306 )
cur = db.cursor() 
cur.execute('use xxx;')

for t in tables:
    print t
    curpost.execute( "truncate table " + t[0] )
    cur.execute("select * from "+ t[0] )
    a = ','.join( '%s' for i in range(t[1]) )
    qry = "insert into " + t[0]  + " values ( " + a +" )" 
    print qry
    i = 0
    while True:
        rows = cur.fetchmany(5000)
        if not rows: break
        string = ''
        for row in rows:
            string = string +  ('|'.join([str(x) for x in row])) + "\n"                
        curpost.copy_from(StringIO(string),  t[0], sep="|", null="None" )
        i += curpost.rowcount
        print i  , " loaded"
        curpost.connection.commit()        
        del string, row, rows
        gc.collect()        

curpost.close()
cur.close()

Для небольших таблиц код работает нормально. Однако, чем больше (3,6 миллиона записей), в тот момент, когда исполняется mysql (cur.execute("select * from "+ t[0])), использование памяти на машине увеличивается. Это даже при том, что я использовал fetchmany и записи должны поступать только партиями по 5000. Я пробовал и с 500 записями, и это то же самое. Для больших таблиц кажется, что fetchmany работает не так, как задокументировано.

Редактировать - я добавил сборщик мусора и операторы del. Тем не менее, память продолжает раздуваться, пока все записи не будут обработаны.

Есть идеи?

1 ответ

Извините, если я ошибаюсь, вы сказали, что не хотите менять запрос

Но на тот случай, если у вас нет выбора, вы можете попробовать:

замените этот фрагмент:

cur.execute("select * from "+ t[0] )
a = ','.join( '%s' for i in range(t[1]) )
qry = "insert into " + t[0]  + " values ( " + a +" )" 
print qry
i = 0
while True:
        rows = cur.fetchmany(5000)

к этому:

a = ','.join( '%s' for i in range(t[1]) )
qry = "insert into " + t[0]  + " values ( " + a +" )" 
print qry
i = 0
while True:
    cur.execute("select * from "+ t[0]+" LIMIT "+i+", 5000")
    rows = cur.fetchall()
Другие вопросы по тегам