python - 如何使用并发在 Python 中迁移数据库?
问题描述
我有一个用于将数据从 SQLite 迁移到 Postgres 的脚本。我只是使用 for 循环来一张一张地传输表格。现在,我想尝试使用线程、多处理或异步同时传输多个表,以加速程序以比较这些方式之间的运行时。你如何做其中一种方式?
这是我的脚本:
import psycopg2, sqlite3, sys
import time
import multiprocessing
sqdb="C://Users//duongnb//Desktop//Python//SqliteToPostgreFull//testmydb6.db"
sqlike="table"
pgdb="testmydb11"
pguser="postgres"
pgpswd="1234"
pghost="127.0.0.1"
pgport="5432"
consq=sqlite3.connect(sqdb)
cursq=consq.cursor()
tabnames=[]
print()
cursq.execute('SELECT name FROM sqlite_master WHERE type="table" AND name LIKE "%table%";')
tabgrab = cursq.fetchall()
for item in tabgrab:
tabnames.append(item[0])
print(tabgrab)
def copyTable(table):
print(table)
cursq.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name = ?;", (table,))
create = cursq.fetchone()[0]
cursq.execute("SELECT * FROM %s;" %table)
rows=cursq.fetchall()
colcount=len(rows[0])
pholder='%s,'*colcount
newholder=pholder[:-1]
try:
conpg = psycopg2.connect(database=pgdb, user=pguser, password=pgpswd,
host=pghost, port=pgport)
curpg = conpg.cursor()
curpg.execute("DROP TABLE IF EXISTS %s;" %table)
create = create.replace("AUTOINCREMENT", "")
curpg.execute(create)
curpg.executemany("INSERT INTO %s VALUES (%s);" % (table, newholder),rows)
conpg.commit()
if conpg:
conpg.close()
except psycopg2.DatabaseError as e:
print ('Error %s' % e)
sys.exit(1)
finally:
print("Complete")
consq.close()
if __name__ == "__main__":
start_time = time.time()
for table in tabnames:
p = multiprocessing.Process(target = copyTable, args = (table))
p.start()
for table in tabnames:
p.join()
print("All processes finished.")
duration = time.time() - start_time
print(f"Duration {duration} seconds")
解决方案
您应该将内部for table in tabnames
放入一个函数中,例如copyTable
. 然后您就可以使用该multiprocessing
包来并行化您的代码。它应该看起来像这样:
for table in tabnames:
p = multiprocessing.Process(target = copyTable, args = (table))
p.start()
for table in tabnames:
p.join()
print("All processes finished.")
COPY
但是,如果您使用( https://www.postgresql.org/docs/current/sql-copy.html ) 而不是许多INSERT
命令,则可以进一步加快代码速度。
除了multiprocessing
模块,您还可以使用threading
模块,它的工作方式非常相似。然后你有线程而不是进程。由于解释器锁定,我预计性能会更差。
推荐阅读
- macos-sierra - 为什么一个蒸汽“你好”项目在 Sierra 启动后就被粉碎了?
- c# - 如何从触摸板获取鼠标滚动?
- homebrew - 如何修复在 Mac Mojave 中安装 xmgrace 时出现的错误?
- sql - 在 WHILE LOOP 中插入记录时发生的奇怪的 TRY CATCH 行为
- d3.js - D3js 使用手动绘制的圆圈进行缩放
- javascript - Javascript点击切换
- email-parsing - 如何从收据电子邮件中提取金额
- git - 第一次尝试安装git-osx,下载什么也没做
- apache-kafka - 从 kafka 主题中删除单个记录
- deep-learning - 是否可以在智能手机上使用 Tensoflow Lite/或任何其他框架训练神经网络模型?