用Python将MySQL表复制到SQLite3

2 投票
3 回答
5305 浏览
提问于 2025-04-16 00:28

我有一个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(操作, 参数序列)
这个方法是用来准备一个数据库操作(查询或命令),然后对序列中的所有参数序列或映射进行执行。

撰写回答