用Python将MySQL表复制到SQLite3
我有一个MySQL的表,里面大约有1000万行数据。我在SQLite3中创建了一个并行的结构,现在想把这个表的数据复制过去。用Python来做这个似乎是个可以接受的方案,但这样做——
# ...
mysqlcursor.execute('SELECT * FROM tbl')
rows = mysqlcursor.fetchall() # or mysqlcursor.fetchone()
for row in rows:
# ... insert row via sqlite3 cursor
...速度慢得惊人(在.execute()
这一步卡住了,我也不知道要等多久)。
我只需要做一次这个操作,所以如果花几个小时我也不在乎,但有没有其他的方法可以做到呢?用其他工具而不是Python也可以。
3 个回答
0
你可以通过使用“select into outfile”命令从MySQL导出一个平面文件,然后用SQLite的.import命令导入这些文件。
mysql> SELECT * INTO OUTFILE '/tmp/export.txt' FROM sometable;
sqlite> .separator "\t"
sqlite> .import /tmp/export.txt sometable
这样可以处理数据的导出和导入,但当然不能复制数据库的结构。
如果你真的想用Python来做这个(可能是为了转换数据),我建议使用MySQLdb.cursors.SSCursor来逐行读取数据。否则,MySQL的查询结果会被缓存到内存中,这就是为什么你的查询在执行时会卡住。所以代码大概是这样的:
import MySQLdb
import MySQLdb.cursors
connection = MySQLdb.connect(...)
cursor = connection.cursor(MySQLdb.cursors.SSCursor)
cursor.execute('SELECT * FROM tbl')
for row in cursor:
# do something with row and add to sqlite database
不过,这种方法会比导出和导入的方式慢很多。
3
最简单的方法可能是使用mysqldump这个工具,把整个数据库导出成一个SQL文件,然后再用SQLite的命令行工具来执行这个文件。
3
你没有具体说明你是怎么插入数据的,但你提到了 execute()
。
你可以试试 executemany()
,这样可能更好。
比如:
import sqlite3
conn = sqlite3.connect('mydb')
c = conn.cursor()
# one '?' placeholder for each column you're inserting
# "rows" needs to be a sequence of values, e.g. ((1,'a'), (2,'b'), (3,'c'))
c.executemany("INSERT INTO tbl VALUES (?,?);", rows)
conn.commit()
*executemany()
的用法可以参考 Python DB-API:
.executemany(操作, 参数序列)
这个方法是用来准备一个数据库操作(查询或命令),然后对序列中的所有参数序列或映射进行执行。