Python将MySQL表复制到SQLite3

时间:2021-09-12 05:34:06

I've got a MySQL table with about ~10m rows. I created a parallel schema in SQLite3, and I'd like to copy the table somehow. Using Python seems like an acceptable solution, but this way --

我有一个大约10米行的MySQL表。我在SQLite3中创建了一个并行模式,我想以某种方式复制表。使用Python似乎是一个可接受的解决方案,但这种方式 -

# ...
mysqlcursor.execute('SELECT * FROM tbl')
rows = mysqlcursor.fetchall() # or mysqlcursor.fetchone()
  for row in rows:
    # ... insert row via sqlite3 cursor

...is incredibly slow (hangs at .execute(), I wouldn't know for how long).

...非常慢(挂在.execute(),我不知道多长时间)。

I'd only have to do this once, so I don't mind if it takes a couple of hours, but is there a different way to do this? Using a different tool rather than Python is also acceptable.

我只需要做一次,所以我不介意是否需要几个小时,但有不同的方法吗?使用不同的工具而不是Python也是可以接受的。

3 个解决方案

#1


3  

The simplest way might be to use mysqldump to get a SQL file of the whole db, then use the SQLite command-line tool to execute the file.

最简单的方法可能是使用mysqldump获取整个db的SQL文件,然后使用SQLite命令行工具来执行该文件。

#2


3  

You don't show exactly how you insert rows, but you mention execute().

您没有准确显示插入行的方式,但提到了execute()。

You might try executemany()* instead.
For example:

您可以尝试使用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() as described in the Python DB-API:

* Python DB-API中描述的executemany():

.executemany(operation,seq_of_parameters)
Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.

.executemany(operation,seq_of_parameters)准备数据库操作(查询或命令),然后针对序列seq_of_parameters中找到的所有参数序列或映射执行它。

#3


0  

You can export a flat file from mysql using select into outfile and import those with sqlite's .import:

您可以使用select into outfile从mysql导出平面文件,并使用sqlite的.import导入它们:

mysql> SELECT * INTO OUTFILE '/tmp/export.txt' FROM sometable;

sqlite> .separator "\t"
sqlite> .import /tmp/export.txt sometable

This handles the data export/import but not copying the schema, of course.

当然,这会处理数据导出/导入,但不会复制模式。

If you really want to do this with python (maybe to transform the data), I would use a MySQLdb.cursors.SSCursor to iterate over the data - otherwise the mysql resultset gets cached in memory which is why your query is hanging on execute. So that would look something like:

如果你真的想用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

That will be much slower than the export/import approach.

这将比出口/进口方法慢得多。

#1


3  

The simplest way might be to use mysqldump to get a SQL file of the whole db, then use the SQLite command-line tool to execute the file.

最简单的方法可能是使用mysqldump获取整个db的SQL文件,然后使用SQLite命令行工具来执行该文件。

#2


3  

You don't show exactly how you insert rows, but you mention execute().

您没有准确显示插入行的方式,但提到了execute()。

You might try executemany()* instead.
For example:

您可以尝试使用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() as described in the Python DB-API:

* Python DB-API中描述的executemany():

.executemany(operation,seq_of_parameters)
Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.

.executemany(operation,seq_of_parameters)准备数据库操作(查询或命令),然后针对序列seq_of_parameters中找到的所有参数序列或映射执行它。

#3


0  

You can export a flat file from mysql using select into outfile and import those with sqlite's .import:

您可以使用select into outfile从mysql导出平面文件,并使用sqlite的.import导入它们:

mysql> SELECT * INTO OUTFILE '/tmp/export.txt' FROM sometable;

sqlite> .separator "\t"
sqlite> .import /tmp/export.txt sometable

This handles the data export/import but not copying the schema, of course.

当然,这会处理数据导出/导入,但不会复制模式。

If you really want to do this with python (maybe to transform the data), I would use a MySQLdb.cursors.SSCursor to iterate over the data - otherwise the mysql resultset gets cached in memory which is why your query is hanging on execute. So that would look something like:

如果你真的想用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

That will be much slower than the export/import approach.

这将比出口/进口方法慢得多。