请教一下 Python 多进程的内容

2016-07-22 16:37:05 +08:00
 slysly759

#起因: 公司让处理大量 excel 数据并导入 oracle ,但是单进程太慢了,于是考虑多线程或多进程,在尝试过网络上很多版本的多线程多进程,但都导入部分数据后退出导致失败具体见下文

#错误原因:

pool=ThreadPool(4)
cqs=cqs_branch_connect()
name_list=cqs_pt_rating().get_path()
connection_id=get_connectionid()
batch_id=get_batch_id()
conn_order_number=get_order_number()
bug_connection_id=0
cqs.make_exceldata(name_list,bug_connection_id,connection_id,batch_id,conn_order_number)
excel_name='new 管道连接.xlsx'
data_list=compliment(header_name,excel_name)
pool.map(insert_db,data_list)


##data_list 少则有千条 多则有上万条,但是 map 加上 pool 并不能将 data_list 数据全额导入进数据库 在执行到开始的某一段就会产生 process Finnished by the code -13000xxxx 的代码 google 是没有相关内容 我想知道这是为什么 并渴望知道解决方案。
###1.我很好奇网上一些多进程的按照这个模式实现的时候 有没有遇到过当 data 过大过多 然后不执行这种情况
###2.我很想知道 多进程是如何在这些列表里面加锁,比如让进程 1 访问 list[1:10]进程二[11:20]....进程 8[80:90] 不让他们发生 race competation 或者如何通过数量来划分哪些列表归谁呢?


####PS:尝试过的并发: multipletreading 还是旗下的 dummy 亦或是 3.x 新出来的 concurrent.futures
2598 次点击
所在节点    Python
9 条回复
fzinfz
2016-07-22 20:24:53 +08:00
建议直接用 MS 家的 OLEDB ,然后用官方的 SqlBulkCopy 复制 Table 。
C#代码参考:

```
namespace XXX_SqlBulkCopy
{
class Program
{
static void Main(string[] args)
{
// Connection String to Excel Workbook
string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=yyy.xlsx;Extended Properties=""Excel 12.0;HDR=YES;""";

// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand
("SELECT * FROM [backlog$]", connection);

connection.Open();

// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=.;Initial Catalog=XXX;Integrated Security=True";

// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "backlog$";
bulkCopy.WriteToServer(dr);
}
}
}
}
}
}


```
zhuangzhuang1988
2016-07-22 20:34:36 +08:00
用 visualstudio 分析一下, 慢在哪里, 再优化..
lizhenda
2016-07-22 21:02:19 +08:00
可以先把数据按你开多少个进程分配好,然后再分别塞给各个进程···如果用抢占式会出现中间断开少文件的情况
Aksura
2016-07-22 21:09:08 +08:00
建议将 excel 文件处理为文本文件,再用 sqlldr 将文本文件导入数据库。
izoabr
2016-07-22 21:36:00 +08:00
何必呢,用工具直接导入不就得了,这事主要是考虑数据完整性,而不是创新性,所以我还是建议用工具,很多免费的工具都支持,能用就用着,有空再研究,而且不要在生产环境上研究。
nyfwan123
2016-07-23 08:47:35 +08:00
建议手动
slysly759
2016-08-01 23:37:16 +08:00
@fzinfz 我在这里统一做一下回复吧:问题解决了 看了国外的文献解决了这个迷之 bug 我把 map 换成了 map_async 虽然不明所以 但是解决了问题。
这不是关键!关键是如果你认为插入数据库并发地插入那就大错特错了,他喵的 sql 有 excutemany 握草 刚好 cx_oracle 在第二章精通 oracle 和 python 写明了:如果不采用多条插入,那么是很浪费效率的。马丹不早说,我当时就把这个破玩儿重写了,效率提高一百倍有木有。一次性插入一百万条爽不爽~
另外,应为是客户要求的,所以一些第三方什么 PLSQL 自带的 excel 导入工具啊 楼下说的 sqlldr 的轮子啊 都不符合要求,客户要的就是一键导入(当然后续又加了什么备份还原啊 上传 SFTP 啊)所以还是硬着头皮上了
slysly759
2016-08-01 23:37:49 +08:00
@zhuangzhuang1988 我统一回复啦~
slysly759
2016-08-01 23:40:49 +08:00
@lizhenda 我的数据都做成字典扔进 list 啦 其实我主要是不太清楚 pool.map 的原理(我没看源码别打我蛤)比如我的 list 有七个 进程并行的有两个,那么按理说是一个一个扔进进程池里面直到没有了为止。应该是这样。
对于你说的这次数据库还没有遇到,我想不远的时候会用到你说的文件锁或者进程间通信之类的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/294242

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX