精华内容
下载资源
问答
  • python 多线程操作数据库
    2017-05-31 13:53:00

    如果使用多线程操作数据库,容易引起多用户操作锁表

    OperationalError: (2013, 'Lost connection to MySQL server during query')

     

    使用多线程时,出现链接服务器消失的错误,在链接数据库时,加入ping(True)方法

    1 conn=MySQLdb.connect('192.168.1.2','root','root','ant',charset='utf8')
    2 cur = conn.cursor()
    3 conn.ping(True)

    意思时检测链接

    转载于:https://www.cnblogs.com/pxfb/p/6923797.html

    更多相关内容
  • python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。 解决方法:使用数据库连接池,并且每次操作都从数据库连接池获取数据库操作句柄,操作完关闭连接返回数据库连接池。 *...
  • python多线程操作数据库问题

    万次阅读 2018-05-22 21:00:42
    python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。解决方法:使用数据库连接池,并且每次操作都从数据库连接池获取数据库操作句柄,操作完关闭连接返回数据库连接池。*...

    python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。

    解决方法:使用数据库连接池,并且每次操作都从数据库连接池获取数据库操作句柄,操作完关闭连接返回数据库连接池。

    *连接数据库需要设置charset = 'utf8', use_unicode = True,不然会报中文乱码问题

    *网上说解决python多线程并发操作数据库问题,连接时使用self.conn.ping(True)(检查并保持长连接),但是我这边亲测无法解决,建议还是使用数据库连接池

    python多线程代码:

    import threading
    
    class MyThread(threading.Thread):
    
    	def __init__(self, name, count, exec_object):
    		threading.Thread.__init__(self)
    		self.name = name
    		self.count = count
    		self.exec_object = exec_object
    
    	def run(self):
    		while self.count >= 0:
    			count = count - 1
    			self.exec_object.execFunc(count)
    
    thread1 = MyThread('MyThread1', 3, ExecObject())
    thread2 = MyThread('MyThread2', 5, ExecObject())
    thread1.start()
    thread2.start()
    thread1.join() # join方法 执行完thread1的方法才继续主线程
    thread2.join() # join方法 执行完thread2的方法才继续主线程
    # 执行顺序 并发执行thread1 thread2,thread1和thread2执行完成才继续执行主线程
    
    # ExecObject类是自定义数据库操作的业务逻辑类
    # 
    
    ########join方法详解########
    thread1 = MyThread('MyThread1', 3, ExecObject())
    thread2 = MyThread('MyThread2', 5, ExecObject())
    thread1.start()
    thread1.join() # join方法 执行完thread1的方法才继续主线程
    thread2.start()
    thread2.join() # join方法 执行完thread2的方法才继续主线程
    # 执行顺序 先执行thread1,执行完thread1再执行thread2,执行完thread2才继续执行主线程

    mysql数据库连接池代码:

    import MySQLdb
    from DBUtils.PooledDB import PooledDB
    
    class MySQL:
    
    	host = 'localhost'
    	user = 'root'
    	port = 3306
    	pasword = ''
    	db = 'testDB'
    	charset = 'utf8'
    
    	pool = None
    	limit_count = 3 # 最低预启动数据库连接数量
    
    	def __init__(self):
    		self.pool = PooledDB(MySQLdb, self.limit_count, host = self.host, user = self.user, passwd = self.pasword, db = self.db,
    			port = self.port, charset = self.charset, use_unicode = True)
    
    	def select(self, sql):
    		conn = self.pool.connection()
    		cursor = conn.cursor()
    		cursor.execute(sql)
    		result = cursor.fetchall()
    		cursor.close()
    		conn.close()
    		return result
    
    	def insert(self, table, sql):
    		conn = self.pool.connection()
    		cursor = conn.cursor()
    		try:
    			cursor.execute(sql)
    			conn.commit()
    			return {'result':True, 'id':int(cursor.lastrowid)}
    		except Exception as err:
    			conn.rollback()
    			return {'result':False, 'err':err}
    		finally:
    			cursor.close()
    			conn.close()
    
    

    展开全文
  • 主要介绍了python使用多线程查询数据库的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要介绍了Python基于多线程实现抓取数据存入数据库的方法,结合实例形式分析了Python使用数据库类与多线程类进行数据抓取与写入数据库操作的具体使用技巧,需要的朋友可以参考下
  • 根据读的结果(需求1)创建若干张数据表,每个时刻只有一个线程在创建表(经测试发现多线程同时创建表会有表创建不出来,为了保险,让同一时刻只有一个线程创建表)。对于同一张表,同一时刻只有一个线程在写;对于...

    需求

    1. 多个线程同时读数据库的一张表,使用数据库连接池。显然数据库连接池的数量就是读线程的数量。
    2. 根据读的结果(需求1)创建若干张数据表,每个时刻只有一个线程在创建表(经测试发现多线程同时创建表会有表创建不出来,为了保险,让同一时刻只有一个线程创建表)。对于同一张表,同一时刻只有一个线程在写;对于不同的表,可以多个线程并发写。

    注意 一定要关闭连接后再释放锁,如果顺序错误则会耗尽数据库连接池的数量。本人新手,好半天才发现问题的原因。

    实现

    1. 数据库连接池用了mysql官方驱动自带的连接池,功能很简单,获取连接和释放连接,最大连接数量32
    import mysql.connector.pooling
    pool = mysql.connector.pooling.MySQLConnectionPool(pool_name = "mypool", pool_size = 32, **db_config)
    
    1. 用信号量控制线程数量。线程数量与数据库连接池数量相等
    import threading
    # 设置信号量初值32,即控制并发线程读数据库为32个
    S_conn = threading.Semaphore(32)
    # 获取信号量,如果信号量为0则线程阻塞在这,不会向下执行
    # 信号量不为0则信号量减1
    if S_conn.require():
      # 在连接池中取一个连接
      conn = pool.get_connection()
      doSomething()
      # 将连接归还到数据库连接池,而不是真的关闭
      conn.close()
      # 释放信号量,信号量加1
      S_conn.release()
    
    1. 多线程使用Threading.Thread包装函数,这个函数就是线程的业务逻辑
    # 其它参数可以自己去搜,三个参数够用了
    t=threading.Thread(target=要包装成线程的函数名,args=(函数的参数列表,多个参数用逗号隔开,一参数后面也要写一个都好),name=线程名)
    # 启动线程
    t.start()
    

    完整代码如下:

    import mysql.connector
    import mysql.connector.pooling
    import threading
    # 自己写的数据配置
    from config import db_config_lm,db_config_pop
    
    
    # 保证每次只有一个线程建表
    # 可以用lock锁,都一样
    S_createTable = threading.Semaphore(1)
    
    # 创建两个数据库的连接池,和他们的信号量
    # 每获取一个次连接信号量减一,等于0时线程阻塞,等待其他线程释放连接后阻塞的线程才能唤醒
    pop_conn_pool = mysql.connector.pooling.MySQLConnectionPool(pool_name = "poppool", pool_size = 32, **db_config_pop)
    S_pop_conn = threading.Semaphore(32)
    lm_conn_pool = mysql.connector.pooling.MySQLConnectionPool(pool_name = "lmpool", pool_size = 32, **db_config_lm)
    S_lm_conn = threading.Semaphore(32)
    
    # 每个线程要做的事,后面用Threading.Thread将该函数包装成线程
    # 建议先从后面的函数main()函数看起,再回来看这个
    # 前两个参数是字符串,lock参数是threading.lock()
    # 参数country相同的传入的lock对象也相同(main函数实现),从而一个country数据表有一个锁,保证了对country表插入时只有一个线程在插入
    def generate_pop(country,city,lock):
        table_name = "pop_"+country
        # 一个国家是一个表,保证每个国家只有一个线程在写
        # 不同的国家用的不同的锁,线程可以同时运行
        if  lock.acquire():
            #print(threading.currentThread().getName()+"获得锁,正在写表:"+table_name)
            try:
            	# 从数据库里获取连接,如果没有连接则线程阻塞,等待其他线程释放连接
            	
    	
    			# 这个信号量实际的作用是控制读的线程数量
    			# 一张表的数据量大时,多个线程同时读,数据库性能降低,有的结果会读不到
    			# 从数据库中读的结果为空
    			# 为了尽量避免这个问题设置了该信号量控制读的线程数量
    			# 同时我的这张数据表用了memory引擎,即把数据表放在了内存里并加了索引,可以加快读的速度
                if S_lm_conn.acquire():
                    conn_lm = lm_conn_pool.get_connection()
                # 这个信号量控制了写不同表的线程数量,即同时可以有32个线程写32张不同的表
                # 上面的lock控制的是一个相同的表只有一个线程在写
                if S_pop_conn.acquire():
                    conn_pop = pop_conn_pool.get_connection()
                # 获取建表的信号量,由于信号量是1,相当于一个锁,同一时刻只有一个线程在建表
                # 经过测试发现多个线程同时建表,有的表会创建不出来,为了保险设置成一个线程建表
                if S_createTable.acquire():
                    try:
                    	# 建表,自己写的模块
                        db.create_table(conn_pop,table_name,db_config_pop)
                    except Exception as e:
                        print(e)
                        print(threading.currentThread().getName()+"建表失败")
                    finally:
                    	# 因为同一时刻只有一个线程能建表,所以建完表要立刻释放信号量
                    	# 不要等到所有执行完再释放这个信号量,否则相当于变成串行执行了
                        S_createTable.release()
    
    			# 读数据库的表
    			# 可以有32个线程同时读
                cursor = conn_lm.cursor()
                sql = "select minip,maxip from `xx_memory` where city='%s'"%(city)
                cursor.execute(sql)
                doSomething()
                
                # 插入数据,相同的表只有一个线程在插入
                cursor_insert = conn_pop.cursor()
                sql = ""
                cursor_insert.execute(sql)
                   
                cursor.close()
                cursor_insert.close()
                
            except Exception as e:
            	# 出现异常的线程名
                print("threading==>"+threading.currentThread().getName())
                print(e)
            finally:
            	# 即使出现异常finally代码块中内容也一定会执行
            	# 在这里要释放数据库连接和锁/信号量,否则会死锁
            	# 一定要在关闭数据库连接后(本例是将连接归还给数据库连接池)再释放锁,
            	# 否则释放锁后其他线程会立刻获取数据库连接,导致连接被耗尽
                lock.release()
                conn_lm.close()
                conn_pop.close()
                
                S_pop_conn.release()
                S_lm_conn.release()
                #print(threading.currentThread().getName()+"释放锁")
    
    def main():
        # 连接数据库,从表中选取不同的国家和城市
        conn = mysql.connector.connect(**db_config)
        cursor = conn.cursor()
        sql = "SELECT DISTINCT country,city from `index_city` "
        cursor.execute(sql)
        threads = []
        
        # 在generate_pop()函数中,一个国家要产生一个表,一个国家的不同城市放在一起
        # 所以一个国家用一个锁锁住表(一个国家创建一个锁),使一张表只有一个线程在插入
        country_last = ''
        for r in cursor.fetchall():
            country = r[0]
         	# 如果国家不一样就新建一个锁
            if country!=country_last:
                lock = threading.Lock()
            country_last = country
            city = r[1]
            # 线程名
            t_name = country+"_"+city
            threads.append(threading.Thread(target=generate_pop,args=(country,city,lock),name=t_name))
    	# 打乱线程
    	# 从数据库中选出不同国家不用城市,同一个国家的不同城市是挨着的,线程启动时国家相同则会只有一个
    	# 线程在插入,效率低。打乱后如果国家不同则可以同时插入数据库
        random.shuffle(threads)
        # 启动线程
        for thread in threads:
            thread.start()
            
            
        
    
    if __name__ == '__main__':
        main()
        
       
    

    以上是程序的框架,我把具体要做的内容删了,填上自己的内容就可以运行了。异常处理要自己弄弄

    展开全文
  • 分享给大家供大家参考,具体如下:python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。解决方法:使用数据库连接池,并且每次操作都从数据库连接池获取数据库操作句柄,操作...

    Python基于多线程操作数据库相关问题分析

    本文实例分析了Python多线程操作数据库相关问题。分享给大家供大家参考,具体如下:

    python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题。

    解决方法:使用数据库连接池,并且每次操作都从数据库连接池获取数据库操作句柄,操作完关闭连接返回数据库连接池。

    *连接数据库需要设置charset = 'utf8', use_unicode = True,不然会报中文乱码问题

    *网上说解决python多线程并发操作数据库问题,连接时使用self.conn.ping(True)(检查并保持长连接),但是我这边亲测无法解决,建议还是使用数据库连接池

    python多线程代码:

    import threading

    class MyThread(threading.Thread):

    def __init__(self, name, count, exec_object):

    threading.Thread.__init__(self)

    self.name = name

    self.count = count

    self.exec_object = exec_object

    def run(self):

    while self.count >= 0:

    count = count - 1

    self.exec_object.execFunc(count)

    thread1 = MyThread('MyThread1', 3, ExecObject())

    thread2 = MyThread('MyThread2', 5, ExecObject())

    thread1.start()

    thread2.start()

    thread1.join() # join方法 执行完thread1的方法才继续主线程

    thread2.join() # join方法 执行完thread2的方法才继续主线程

    # 执行顺序 并发执行thread1 thread2,thread1和thread2执行完成才继续执行主线程

    # ExecObject类是自定义数据库操作的业务逻辑类

    #

    ########join方法详解########

    thread1 = MyThread('MyThread1', 3, ExecObject())

    thread2 = MyThread('MyThread2', 5, ExecObject())

    thread1.start()

    thread1.join() # join方法 执行完thread1的方法才继续主线程

    thread2.start()

    thread2.join() # join方法 执行完thread2的方法才继续主线程

    # 执行顺序 先执行thread1,执行完thread1再执行thread2,执行完thread2才继续执行主线程

    mysql数据库连接池代码:

    import MySQLdb

    from DBUtils.PooledDB import PooledDB

    class MySQL:

    host = 'localhost'

    user = 'root'

    port = 3306

    pasword = ''

    db = 'testDB'

    charset = 'utf8'

    pool = None

    limit_count = 3 # 最低预启动数据库连接数量

    def __init__(self):

    self.pool = PooledDB(MySQLdb, self.limit_count, host = self.host, user = self.user, passwd = self.pasword, db = self.db,

    port = self.port, charset = self.charset, use_unicode = True)

    def select(self, sql):

    conn = self.pool.connection()

    cursor = conn.cursor()

    cursor.execute(sql)

    result = cursor.fetchall()

    cursor.close()

    conn.close()

    return result

    def insert(self, table, sql):

    conn = self.pool.connection()

    cursor = conn.cursor()

    try:

    cursor.execute(sql)

    conn.commit()

    return {'result':True, 'id':int(cursor.lastrowid)}

    except Exception as err:

    conn.rollback()

    return {'result':False, 'err':err}

    finally:

    cursor.close()

    conn.close()

    更多关于Python相关内容感兴趣的读者可查看本站专题:《Python进程与线程操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》、《Python+MySQL数据库程序设计入门教程》及《Python常见数据库操作技巧汇总》

    希望本文所述对大家Python程序设计有所帮助。

    Python多线程原理与用法实例剖析

    本文实例讲述了Python多线程原理与用法。分享给大家供大家参考,具体如下:

    先来看个栗子:

    下面来看一下I/O秘籍型的线程,举个栗子——爬虫,下面是爬下来的图片用4个线程去写文件

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

    import re

    import urllib

    import threading

    import Queue

    import timeit

    def getHtml(url):

    html_page = urllib.urlopen(url).read()

    return html_page

    # 提取网页中图片的URL

    def getUrl(html):

    pattern = r'src="(http://img.*?)"' # 正则表达式

    imgre = re.compile(pattern)

    imglist = re.findall(imgre, html) # re.findall(pattern,string) 在string中寻找所有匹配成功的字符串,以列表形式返回值

    return imglist

    class getImg(threading.Thread):

    def __init__(self, queue, thread_name=0): # 线程公用一个队列

    threading.Thread.__init__(self)

    self.queue = queue

    self.thread_name = thread_name

    self.start() # 启动线程

    # 使用队列实现进程间通信

    def run(self):

    global count

    while (True):

    imgurl = self.queue.get() # 调用队列对象的get()方法从队头删除并返回一个项目

    urllib.urlretrieve(imgurl, 'E:\mnt\girls\%s.jpg' % count)

    count += 1

    if self.queue.empty():

    break

    self.queue.task_done() # 当使用者线程调用 task_done() 以表示检索了该项目、并完成了所有的工作时,那么未完成的任务的总数就会减少。

    imglist = []

    def main():

    global imglist

    url = "http://huaban.com/favorite/beauty/" # 要爬的网页地址

    html = getHtml(url)

    imglist = getUrl(html)

    def main_1():

    global count

    threads = []

    count = 0

    queue = Queue.Queue()

    # 将所有任务加入队列

    for img in imglist:

    queue.put(img)

    # 多线程爬去图片

    for i in range(4):

    thread = getImg(queue, i)

    threads.append(thread)

    # 阻塞线程,直到线程执行完成

    for thread in threads:

    thread.join()

    if __name__ == '__main__':

    main()

    t = timeit.Timer(main_1)

    print t.timeit(1)

    4个线程的执行耗时为:0.421320716723秒

    修改一下main_1换成单线程的:

    def main_1():

    global count

    threads = []

    count = 0

    queue = Queue.Queue()

    # 将所有任务加入队列

    for img in imglist:

    queue.put(img)

    # 多线程爬去图片

    for i in range(1):

    thread = getImg(queue, i)

    threads.append(thread)

    # 阻塞线程,直到线程执行完成

    for thread in threads:

    thread.join()

    单线程的执行耗时为:1.35626623274秒

    155955154G12F-1L28.jpg

    再来看一个:

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

    import threading

    import timeit

    def countdown(n):

    while n > 0:

    n -= 1

    def task1():

    COUNT = 100000000

    thread1 = threading.Thread(target=countdown, args=(COUNT,))

    thread1.start()

    thread1.join()

    def task2():

    COUNT = 100000000

    thread1 = threading.Thread(target=countdown, args=(COUNT // 2,))

    thread2 = threading.Thread(target=countdown, args=(COUNT // 2,))

    thread1.start()

    thread2.start()

    thread1.join()

    thread2.join()

    if __name__ == '__main__':

    t1 = timeit.Timer(task1)

    print "countdown in one thread ", t1.timeit(1)

    t2 = timeit.Timer(task2)

    print "countdown in two thread ", t2.timeit(1)

    task1是单线程,task2是双线程,在我的4核的机器上的执行结果:

    countdown in one thread 3.59939150155

    countdown in two thread 9.87704289712

    天呐,双线程比单线程计算慢了2倍多,这是为什么呢,因为countdown是CPU密集型任务(计算嘛)

    155955154G160-2cP.jpg

    I/O密集型任务:线程做I/O处理的时候会释放GIL,其他线程获得GIL,当该线程再做I/O操作时,又会释放GIL,如此往复;

    CPU密集型任务:在多核多线程比单核多线程更差,原因是单核多线程,每次释放GIL,唤醒的哪个线程都能获取到GIL锁,所以能够无缝执行(单核多线程的本质就是顺序执行),但多核,CPU0释放GIL后,其他CPU上的线程都会进行竞争,但GIL可能会马上又被CPU0(CPU0上可能不止一个线程)拿到,导致其他几个CPU上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,这样会造成线程颠簸(thrashing),导致效率更低。

    更多关于Python相关内容感兴趣的读者可查看本站专题:《Python进程与线程操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》、《Python+MySQL数据库程序设计入门教程》及《Python常见数据库操作技巧汇总》

    希望本文所述对大家Python程序设计有所帮助。

    以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

    展开全文
  • import threading import time import pymysql from sqlalchemy import create_engine import pandas as pd import get_aid_from_docid dbConnectStr = "mysql+pymysql://user:passward@host:port/database?...
  • 场景:公司项目,采取多线程模式定时执行更新某些配置信息,当某两个或多个线程公用一个connect,execute某个sql语句的时候,会造成如下错误。 Packey sequence number wrong - got *** expected 1 解决办法:加...
  • 今天刚看完崔大佬的《python3网络爬虫开发实战》,顿时觉得...为了避免这种尴尬,以及我突然想写博客的心情,我决定还是为大家在进行一次简易爬虫展示,总体程序我会利用多线程的方式来充分利用CPU的空闲时间,其中我也
  • python多线程操作MySQL数据库pymysql项目中使用多线程操作数据库提示错误:pymysql.err.InterfaceError: (0, ”),原因是pymysql的execute有独占锁机制,解决办法是每个线程单独一个数据库连接,为线程增加一个...
  • 下面的案例就是使用线程同时查询出con列表中两个sql的数据并append到全局变量data中 import threading import time import pymysql data= [] def conect(sql): global data # 打开数据库连接 db = pymysql....
  • python使用多线程查询数据库

    万次阅读 热门讨论 2019-02-01 17:04:39
    这样既浪费了cpu资源,又花费了大量时间(当然这里主要说多线程,批量查询不在考虑范围,总会存在不能批量查询的情况),在这种非密集型运算(及大量占用cpu资源)的情况下在python中无疑运用多线程是一个非常棒的...
  • #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Thread): #用于统计csv文件的行数的线程类 def __init__(self,path): threading.Thread.__...
  • 在再每个线程中,将传递过来的参数 update到数据库中,会报一个错误,我想是不是线程同时操作一个,导致锁死?如下图: 其中, conn.connect()我只在程序最开始链接了一次, conn.cloese(),和cursor.close()只在程序...
  • Python3 多线程(连接池)操作MySQL插入数据

    万次阅读 热门讨论 2019-06-01 16:07:55
    DBUtils : 允许在多线程应用和数据库之间连接的模块套件 Threading : 提供多线程功能 2.创建连接池 PooledDB 基本参数: mincached : 最少的空闲连接数,如果空闲连接数小于这个数,Pool自动创建新连接; maxcached ...
  • 多线程,在多线程里面使用运行函数,然后后错 import mysql.connector from mysql.connector import errorcode import threading,time #数据库连接参数 def sqlconn(): dbconfig={'user': 'qrcodeadmin','...
  • python多线程技术爬取天天基金排行榜所有基金数据,结果并保存到excel并写入mysql数据库。基金股票量化分析利器,分分钟获取股票基金数据。
  • 如题,有5个线程,要共享mysql数据库里的某个表,...另外一个线程要视增加了数据后的表格来进行下一步操作 所以是用threading里的lock,还是Event?还是condition?  </p>
  • 【Python高级开发课程 高级教程】课程列表 01 Python语言开发要点详解.pptx 02 Python数据结构.pptx ...08 Python多线程 多进程开发.pptx 09 Python爬虫框架Scrapy实战.pptx 10 Python Web开发框架Django实战.pptx

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 92,992
精华内容 37,196
关键字:

python多线程操作数据库