【发布时间】:2015-02-20 17:04:30
【问题描述】:
我正在将数据从 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()
对于小表,代码运行良好。然而,较大的记录(360 万条记录),当 mysql 执行 (cur.execute("select * from "+ t[0] )) 运行时,机器上的内存利用率会增加。即使我使用了 fetchmany 并且记录应该只分批 5000 条。我也尝试过 500 条记录,它是一样的。对于大表来说,fetchmany 似乎没有像记录的那样工作..
编辑 - 我添加了垃圾收集和 del 语句。直到所有记录都没有被处理,内存仍然会一直膨胀。
有什么想法吗?
【问题讨论】:
-
现在 20 分钟,RAM 使用量约为 4 GB,甚至没有处理 5000 条记录 :-(
-
你说的没有按文档工作是什么意思你能给我一个链接吗?
-
我所说的记录的意思是内存只能用于 5000 条记录的批次中。 Python 进程不断累积内存.. 似乎它获取了所有 360 万条记录而不是进行 fetchmany
-
所以我之前看到了那个链接 - 没有关于内存使用的内容 - 函数只返回询问的行数。因此,如果您关心内存使用并且发现了这个错误,最好将查询更改为使用
LIMIT语句
标签: python mysql mysql-python