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

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

前言

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

要实现对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()

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

(0)

相关推荐

  • 利用python生成一个导出数据库的bat脚本文件的方法

    实例如下: # 环境: python3.x def getExportDbSql(db, index): # 获取导出一个数据库实例的sql语句 sql = 'mysqldump -u%s -p%s -h%s -P%d --default-character-set=utf8 --databases mu_ins_s%s > %s.s%d.mu_ins_%d.sql' %(db['user'], db['pwd'], db['host'], db['port'], index, db['serv

  • Python 实现数据库更新脚本的生成方法

    我在工作的时候,在测试环境下使用的数据库跟生产环境的数据库不一致,当我们的测试环境下的数据库完成测试准备更新到生产环境上的数据库时候,需要准备更新脚本,真是一不小心没记下来就会忘了改了哪里,哪里添加了什么,这个真是非常让人头疼.因此我就试着用Python来实现自动的生成更新脚本,以免我这烂记性,记不住事. 主要操作如下: 1.在原先 basedao.py 中添加如下方法,这样旧能很方便的获取数据库的数据,为测试数据库和生产数据库做对比打下了基础. def select_database_stru

  • 详解python脚本自动生成需要文件实例代码

    python脚本自动生成需要文件 在工作中我们经常需要通过一个文件写出另外一个文件,然而既然是对应关系肯定可以总结规律让计算机帮我们完成,今天我们就通过一个通用文件生成的python脚本来实现这个功能,将大家从每日重复的劳动中解放! 定义一个函数 def produceBnf(infilename,outfilename): List=[] with open(infilename,'r') as inf: for line in inf.readlines(): List.append(re.

  • 在Python中编写数据库模块的教程

    在一个Web App中,所有数据,包括用户信息.发布的日志.评论等,都存储在数据库中.在awesome-python-app中,我们选择MySQL作为数据库. Web App里面有很多地方都要访问数据库.访问数据库需要创建数据库连接.游标对象,然后执行SQL语句,最后处理异常,清理资源.这些访问数据库的代码如果分散到各个函数中,势必无法维护,也不利于代码复用. 此外,在一个Web App中,有多个用户会同时访问,系统以多进程或多线程模式来处理每个用户的请求.假设以多线程为例,每个线程在访问数据库

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

    这篇主要记录一下如何实现对数据库的并行运算来节省代码运行时间.语言是Python,其他语言思路一样. 前言 一共23w条数据,是之前通过自然语言分析处理过的数据,附一张截图: 要实现对news主体的读取,并且找到其中含有的股票名称,只要发现,就将这支股票和对应的日期.score写入数据库. 显然,几十万条数据要是一条条读写,然后在本机上操作,耗时太久,可行性极低.所以,如何有效并行的读取内容,并且进行操作,最后再写入数据库呢? 并行读取和写入 并行读取:创建N*max_process个进程,对数

  • Python利用pdfplumber实现读取PDF写入Excel

    目录 一.Python操作PDF 13大库对比 二.pdfplumber模块 1.安装 2. 加载PDF 3. pdfplumber.PDF类 4. pdfplumber.Page类 三.实战操作 1. 提取单个PDF全部页数 2. 批量提取多个PDF文件 一.Python操作PDF 13大库对比 PDF(Portable Document Format)是一种便携文档格式,便于跨操作系统传播文档.PDF文档遵循标准格式,因此存在很多可以操作PDF文档的工具,Python自然也不例外. Pyth

  • Python 操作pdf pdfplumber读取PDF写入Exce

    目录 1. Python 操作pdf(pdfplumber读取PDF写入Exce) 1.1 安装pdfplumber模块库 1.2 常用操作 1.2.1 Python读取pdf文件案例 1.2.2 Python读取pdf文件代码 1.2.3 Python读取pdf文件存入Excel代码 1. Python 操作pdf(pdfplumber读取PDF写入Exce) 1.1 安装pdfplumber模块库 安装pdfplumber: pip install pdfplumber pdfplumber

  • Python中文件的读取和写入操作

    从文件中读取数据 读取整个文件 这里假设在当前目录下有一个文件名为'pi_digits.txt'的文本文件,里面的数据如下: 3.1415926535 8979323846 2643383279 with open('pi_digits.txt') as f: # 默认模式为'r',只读模式 contents = f.read() # 读取文件全部内容 print contents # 输出时在最后会多出一行(read()函数到达文件末会返回一个空字符,显示出空字符就是一个空行) print '

  • python保存字典和读取字典的实例代码

    读取一个已经保存了的字典 f = open('dict_th','r') a = f.read() dict_hi = eval(a) f.close() 保存一个字典 dict = {} list1 = [] list2 = [] for line in lines: line = line.strip() if ">" in line: list1.append(line) else: list2.append(line) for i in range(): dict[lis

  • python网络编程之读取网站根目录实例

    本文实例讲述了python网络编程之读取网站根目录的方法,分享给大家供大家参考. 具体实现方法如下: import socket, sys port = 70 host = "quux.org" filename = "//" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.sendall(filename+"\r\n") while(

  • Android持久化技术之文件的读取与写入实例详解

    本文实例分析了Android持久化技术之文件的读取与写入操作.分享给大家供大家参考,具体如下: 1.文件存储 (1)在Android的持久化技术中,文件存储是最基本的一种数据存储方式. (2)对存储的内容部做任何处理,原样存储到文件中. (3)Context提供了文件写入与读取的方法,openFileOutput:写入到文件:openFileInput:从文件中读取. (4)文件写入时模式有多种:比如是覆盖写入还是追加写入等. (5)写入的文件默认存储在/data/data/报名/files/目

  • PHP5.5基于mysqli连接MySQL数据库和读取数据操作实例详解

    本文实例讲述了PHP5.5基于mysqli连接MySQL数据库和读取数据操作.分享给大家供大家参考,具体如下: 在学习1. 开启PHP的API支持 (1)首先修改您的php.ini的配置文件. 查找下面的语句: ;extension=php_mysqli.dll 将其修改为: extension=php_mysqli.dll (2)重新启动Apache/IIS,即可. (3)说明:PHP需要单独的文件来支持这个扩展库,一般在PHP目录下的ext目录里能找到php_mysqli.dll文件(PHP

  • asp OpenTextFile文本读取与写入实例代码

    object.OpenTextFile(filename[, iomode[, create[, format]]])  参数  object :必选项.应为 FileSystemObject 对象的名称.  filename :必选项.字符串表达式,指明要打开的文件名称.  iomode :可选项.输入/输出模式,是下列三个常数之一:ForReading,ForWriting,或 ForAppending.  create :可选项.Boolean 值,指出当指定的 filename 不存在时

  • 使用Python对Dicom文件进行读取与写入的实现

    Pydicom 单张影像的读取 使用 pydicom.dcmread() 函数进行单张影像的读取,返回一个pydicom.dataset.FileDataset对象. import os import pydicom # 调用本地的 dicom file folder_path = r"D:\Files\Data\Materials" file_name = "PA1_0001.dcm" file_path = os.path.join(folder_path,fi

随机推荐