Python实现数据库并行读取和写入实例


Posted in Python onJune 09, 2017

这篇主要记录一下如何实现对数据库的并行运算来节省代码运行时间。语言是Python,其他语言思路一样。

前言

一共23w条数据,是之前通过自然语言分析处理过的数据,附一张截图:

Python实现数据库并行读取和写入实例

要实现对news主体的读取,并且找到其中含有的股票名称,只要发现,就将这支股票和对应的日期、score写入数据库。

显然,几十万条数据要是一条条读写,然后在本机上操作,耗时太久,可行性极低。所以,如何有效并行的读取内容,并且进行操作,最后再写入数据库呢?

并行读取和写入

并行读取:创建N*max_process个进程,对数据库进行读取。读取的时候应该注意:

  1. 每个进程需要分配不同的connection和对应的cursor,否则数据库会报错。
  2. 数据库必须能承受相应的高并发访问(可以手动更改)

实现的时候,如果不在进程里面创建新的connection,就会发生冲突,每个进程拿到权限后,会被下个进程释放,所以汇报出来NoneType Error的错误。

  1. 并行写入:在对数据库进行更改的时候,不可以多进程更改。所以,我们需要根据已有的表,创建max_process-1个同样结构的表用来写入。表的命名规则可以直接在原来基础上加上1,2,3...数字可以通过对max_process取余得到。

此时,对应进程里面先后出现读入的conn(保存消息后关闭)和写入的conn。每个进程对应的表的index就是 主循环中的num对max_process取余(100->4,101->5),这样每个进程只对一个表进行操作了。

部分代码实现

max_process = 16 #最大进程数

def read_SQL_write(r_host,r_port,r_user,r_passwd,r_db,r_charset,w_host,w_port,w_user,w_passwd,w_db,w_charset,cmd,index=None):
  #得到tem字典保存着信息
  try:
    conn = pymysql.Connect(host=r_host, port=r_port, user=r_user, passwd =r_passwd, db =r_db, charset =r_charset)
    cursor = conn.cursor()
    cursor.execute(cmd)
  except Exception as e:
    error = "[-][-]%d fail to connect SQL for reading" % index
    log_error('error.log',error)
    return 
  else:
    tem = cursor.fetchone()
    print('[+][+]%d succeed to connect SQL for reading' % index)
  finally:
    cursor.close()
    conn.close()
  
  try:
    conn = pymysql.Connect(host=w_host, port=w_port, user=w_user, passwd =w_passwd, db =w_db, charset =w_charset)
    cursor = conn.cursor()
    cursor.execute(cmd)
  except Exception as e:
    error = "[-][-]%d fail to connect SQL for writing" % index
    log_error('error.log',error)
    return 
  else:
    print('[+][+]%d succeed to connect SQL for writing' % index)
  
  
  r_dict = dict()
  r_dict['id'] = tem[0]
  r_dict['content_id'] = tem[1]
  r_dict['pub_date'] = tem[2]
  r_dict['title'] = cht_to_chs(tem[3])
  r_dict['title_score'] =tem[4]![](http://images2015.cnblogs.com/blog/1172464/201706/1172464-20170609000900309-1810357590.png)

  r_dict['news_content'] = cht_to_chs(tem[5])
  r_dict['content_score'] = tem[6]
  
  for key in stock_dict.keys():
    #能找到对应的股票
    if stock_dict[key][1] and ( r_dict['title'].find(stock_dict[key][1])!=-1 or r_dict['news_content'].find(stock_dict[key][1])!=-1 ):
      w_dict=dict()
      w_dict['code'] = key
      w_dict['english_name'] = stock_dict[key][0]
      w_dict['cn_name'] = stock_dict[key][1]
      #得到分数
      if r_dict['title_score']:
        w_dict['score']=r_dict['title_score']
      else:
        w_dict['score']=r_dict['content_score']
      
      #开始写入
      try:
        global max_process
        cmd = "INSERT INTO dyx_stock_score%d VALUES ('%s', '%s' , %d , '%s' , '%s' , %.2f );" % \
          (index%max_process ,r_dict['content_id'] ,r_dict['pub_date'] ,w_dict['code'] ,w_dict['english_name'] ,w_dict['cn_name'] ,w_dict['score'])
        cursor.execute(cmd)
        conn.commit()
      except Exception as e:
        error = "  [-]%d fail to write to SQL" % index
        cursor.rollback()
        log_error('error.log',error)
      else:
        print("  [+]%d succeed to write to SQL" % index)

  cursor.close()
  conn.close()
def main():
  num = 238143#数据库查询拿到的总数
  p = None
  for index in range(1,num+1):
    if index%max_process==1:
      if p:
        p.close()
        p.join()
      p = multiprocessing.Pool(max_process)
    r_cmd = ('select id,content_id,pub_date,title,title_score,news_content,content_score from dyx_emotion_analysis where id = %d;' % (index))
    p.apply_async(func = read_SQL_write,args=(r_host,r_port,r_user,r_passwd,r_db,r_charset,w_host,w_port,w_user,w_passwd,w_db,w_charset,r_cmd,index,))

  if p:
    p.close()
    p.join()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Django的URLconf中使用多个视图前缀的方法
Jul 18 Python
python分割列表(list)的方法示例
May 07 Python
解决pandas read_csv 读取中文列标题文件报错的问题
Jun 15 Python
python读取excel指定列数据并写入到新的excel方法
Jul 10 Python
使用python3构建文件传输的方法
Feb 13 Python
python登录WeChat 实现自动回复实例详解
May 28 Python
pytorch程序异常后删除占用的显存操作
Jan 13 Python
tensorflow对图像进行拼接的例子
Feb 05 Python
pytorch中使用cuda扩展的实现示例
Feb 12 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
Apr 16 Python
python实现数学模型(插值、拟合和微分方程)
Nov 13 Python
分享提高 Python 代码的可读性的技巧
Mar 03 Python
详解python之多进程和进程池(Processing库)
Jun 09 #Python
Python使用django搭建web开发环境
Jun 09 #Python
Python实现删除文件中含“指定内容”的行示例
Jun 09 #Python
Python实现两个list对应元素相减操作示例
Jun 09 #Python
Python实现向服务器请求压缩数据及解压缩数据的方法示例
Jun 09 #Python
python爬虫框架talonspider简单介绍
Jun 09 #Python
python实现list元素按关键字相加减的方法示例
Jun 09 #Python
You might like
弄了个检测传输的参数是否为数字的Function
2006/12/06 PHP
php中instanceof 与 is_a()区别分析
2015/03/03 PHP
PHP设计模式之简单投诉页面实例
2016/02/24 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
php获取今日开始时间和结束时间的方法
2017/02/27 PHP
php把字符串指定字符分割成数组的方法
2018/03/12 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
ThinkPHP框架实现FTP图片上传功能示例
2019/04/08 PHP
jquery ready函数源代码研究
2009/12/06 Javascript
jQuery实现异步获取json数据的2种方式
2014/08/29 Javascript
js焦点文字滚动效果代码分享
2015/08/25 Javascript
实现非常简单的js双向数据绑定
2015/11/06 Javascript
javascript每日必学之运算符
2016/02/16 Javascript
JavaScript编写带旋转+线条干扰的验证码脚本实例
2016/05/30 Javascript
简单实现JavaScript图片切换效果
2016/11/28 Javascript
js分页之前端代码实现和请求处理
2017/08/04 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
JS+JQuery实现无缝连接轮播图
2020/12/30 jQuery
[10:49]2014国际邀请赛 叨叨刀塔第二期为真正的电竞喝彩
2014/07/21 DOTA
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
利用python获取Ping结果示例代码
2017/07/06 Python
浅谈Pycharm最有必要改的几个默认设置项
2020/02/14 Python
Python flask框架端口失效解决方案
2020/06/04 Python
Python 的 __str__ 和 __repr__ 方法对比
2020/09/02 Python
HTML5中视频音频的使用详解
2017/07/07 HTML / CSS
HTML5未来发展趋势
2016/02/01 HTML / CSS
【HTML5】3D模型--百行代码实现旋转立体魔方实例
2016/12/16 HTML / CSS
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
建筑安全生产目标责任书
2014/07/23 职场文书
科学发展观活动总结
2014/08/28 职场文书
财政专业大学生职业生涯规划书
2014/09/17 职场文书
2014年物业公司工作总结
2014/11/22 职场文书
大学生求职自荐信范文
2015/03/04 职场文书
深度好文:50条没人告诉你的人生经验,句句精辟
2019/08/22 职场文书