将 Excel 上传网站并导入数据库,如何进行设计?

2018-09-19 20:15:18 +08:00
 Kcelone

tornado + celery + redis + mysql。

1.由于当 Excel 文件过大时,上传及导入数据库时需花费较长时间,所以采用 celery 异步处理,首先将 Excel 保存作为临时文件上传保存服务端本地,然后进行 Excel 文件解析操作,并将数据导入数据库。

2.导入时牵扯到数据重复问题,此时采用临时表进行数据去重,当前实现的方式是原生 sql ( orm 有点 hold 不住),创建临时表, 临时表去重, 然后临时表及主表进行 join 筛选出新数据,然后进行插入。经过一番折腾,算是达到了预期目标,然后再继续下面的坑。

3.导入后,需将导入结果返回给界面,比如 Excel 中的数据是有问题的,由于 celery 异步方式,无法将结果返回给主程, 所以请教了下别人,说是可借助数据库新建一张表,负责记录导入结果。

  1. 那么,下面就是新建表的问题,如何建这个表呢? 个人觉得需要有个字段来记录导入的数据的唯一性,然后通过这个字段进行筛选查询当前导入的是哪些个数据。

我的思路就是这了,我想问一下有没有别的方式,好的方式,主要问题就是在这个异步线程结果获取这里,因为上传导入数据库是需要花费不定时时间的,无法上传后立刻判断 celery 的 task 的 id 和状态。

4137 次点击
所在节点    Python
34 条回复
Kcelone
2018-09-20 10:17:50 +08:00
@Eds1995 我等下就看看 celery 的状态获取方面的东西,希望有接口可以使用,我想在前端这边搞个轮训监听,反复查询 celery 处理状态,然后再设置个超时时间,不知道可行不?
Kcelone
2018-09-20 10:19:00 +08:00
@valkyrja backend 是 redis,我等下就研究下这个思路。感谢
lihongjie0209
2018-09-20 10:19:16 +08:00
@Kcelone 在 celery 处理过程中如果需要通知前端, 那就产生一个消息放到 redis 或者消息队列中, 前端轮询就好了
Kcelone
2018-09-20 10:21:01 +08:00
@sonyxperia 如果你要去重的话,可以这么搞,我去重就是这么个思路,然后销毁 tableA,当然我使用的是临时表,表名根据一定的规则进行命名,防止重复建表。
Kcelone
2018-09-20 10:22:58 +08:00
嗯,这里有个疑问就是前端轮询也是要花费一些时间的吧,那么界面是不是就卡在那里了。。
draguo
2018-09-20 10:44:38 +08:00
所以你这个是异步处理,同步通知结果?
sampeng
2018-09-20 10:50:03 +08:00
emmm。。
理一下逻辑?
先,上传。前端显示上传成功。后台开始异步工作。生成 taskid。和前端上传的那条记录绑定。前台可以看到这条任务是处理中。后台随时可以根据 taskid 修改这个状态。
你既然已经是异步了。前端不可能同步显示。一定也是一个异步显示。就看体验了
Kcelone
2018-09-20 13:31:39 +08:00
@saulshao 目前是将日志进行持久化了,然而我该什么时候去查询这些日志呢?这是个问题,所以我才想到去监听 celery 的处理结果,等状态更新为 SUCCESS 的时候,再去数据库查询这些日志,然而这就引出另一个问题,就是轮询时间等待的问题,文件稍微大点,岂不要等很久。。。
Kcelone
2018-09-20 13:36:00 +08:00
@sampeng 嗯,当前也是改成这个样子了,做成非实时显示的了,上传后立刻就返回上传成功之类,然后同时开始异步处理,提供另外一个接口进行结果查询。
Kcelone
2018-09-20 13:38:42 +08:00
@draguo 因为做了些尝试,发现可以获取到异步处理的 id 及状态,所以原本想着,前端这边做个轮询的机制,进行同步结果反馈,做出来的效果的话,就像你在页面上提交东西,页面按钮进行转圈那种等待效果,感觉是这样。
Kcelone
2018-09-20 13:43:58 +08:00
@draguo 或着就是做成分步完成该需求,1. 文件上传,异步处理,2.查询产生的日志。
saulshao
2018-09-20 14:11:24 +08:00
日志持久化的时候,记录日志的相关信息,例如当时处理的文件名,是谁上传的,当时上传的时间戳等,然后根据日志记录的相关信息进行查询。
Kcelone
2018-09-20 14:23:35 +08:00
@saulshao 嗯,类似于“ cots_18_09_20_Sep_09_1537423865 ”这样的,记录日志的数据表里 key 字段,我就三个字段,id,key, msg,这个 key 在第一步上传处理时,已经产生,请求发出后,会将其返回,用以第二步中的日志查询。目前采用的就是这种方式了,以后有新的想法,再持续更新吧,感觉做的还是有点 low。
Kcelone
2018-09-28 10:52:09 +08:00
想来想去,要搞个 Python 后端的技术研发群,群号:902788038,欢迎各位 Python 小伙伴加入,欢迎各位有志者在群里拉帮结派搞事情。

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

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

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

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

© 2021 V2EX