[python] 连接MySQL操作

环境:Linux CentOS6.7,python 2.7.13

说明:连接MySQL,进行增删改查操作,并将执行的SQL和耗时记录到日志里

demo:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import MySQLdb
import logging
import time

‘‘‘
设置日志输出路径和格式
‘‘‘
logging.basicConfig(level=logging.INFO,
                    format=‘%(asctime)s %(levelname)s %(message)s‘,
                    datefmt=‘%Y-%m-%d %H:%M:%S‘,
                    filename=‘/home/sql.log‘,
                    filemode=‘a+‘)

‘‘‘
执行的SQL语句可能有多个,可以在这边进行组装
‘‘‘
def sql_assemble(*args):
    sql_list = [
        ‘delete from table_a where id = %s‘ % args[0],
        ‘delete from table_b where content in %s‘ % args[1],
        ‘update table_c set aa = %s‘ % args[2],
    ]
    return sql_list

class mysqlopr(object):
    def __init__(self,ip,port,username,password,dbname,char_set=‘utf8‘):
	‘‘‘
	创建对象的时候就要求将参数传入进来
	‘‘‘
        self.ip = ip
        self.port = port
        self.username = username
        self.password = password
        self.dbname = dbname
        self.char_set = char_set

    def connect(self):
	‘‘‘
	mysql如果开启了安全模式,insert、delete和update无法执行,需要先设置SET SQL_SAFE_UPDATES = 0
	执行单条SQL,使用execute(),执行多条SQL,可以使用executemany(),但只有INSERT和REPLACE会执行的快点。说明如下
	executemany:This method improves performance on multiple-row INSERT and REPLACE. Otherwise it is equivalent to looping over args with execute().
	‘‘‘
        self.db = MySQLdb.connect(host=self.ip,port = self.port,user=self.username,passwd=self.password,db =self.dbname,charset=self.char_set)
        self.cursor = self.db.cursor()
        #sql_s = ‘SET SQL_SAFE_UPDATES = 0‘
        #self.cursor.execute(sql_s)
        logging.info(‘link to mysqldb: ‘+self.dbname)
    def select(self,sql): 
	‘‘‘
	sst :查询开始时间
	set :查询结束时间
	fetchone(): 只返回一行
	fetchall(): 返回所有行
	fetchmany(size): 返回size行
	rowcount: 这是一个long型只读属性,返回执行execute()方法后影响的行数。

	‘‘‘
        try:
            logging.info(sql)
            self.index_list = []
            sst = time.time()
            self.cursor.execute(sql)
            set = time.time()
			#select_result = self.cursor.fetchone()
			#select_result = self.cursor.fetchmany(10)
            select_result = self.cursor.fetchall()
            #print self.cursor.rowcount,type(self.cursor.rowcount)
            logging.info(‘select count: ‘ + self.cursor.rowcount + ‘, cost :‘ + str(sst - set))
        except Exception as e:
            print e
            logging.error("Error: unable to fecth data" + str(e))
    def insert(self):
	‘‘‘
	和其他方法类似,这边省略
	‘‘‘
        pass
    def update(self):
	‘‘‘
	和其他方法类似,这边省略
	‘‘‘
        pass
    def delete(self,sql):
	‘‘‘
	dst:删除操作开始时间
	det:删除操作结束时间
	删除成功提交,失败回滚
	‘‘‘
        try:
            logging.info(sql)
            dst = time.time()
            self.cursor.execute(sql)
            self.commit()
            det = time.time()
            logging.info(‘delete row: ‘ + str(self.cursor.rowcount) + ‘, cost :‘ + str(det - dst))
        except Exception as e:
            print e
            self.rollback()
            logging.error(str(sql) + ‘,‘ + str(e))
    def commit(self):
        self.db.commit()
    def rollback(self):
        self.db.rollback()
    def close(self):
       self.cursor.close()
       self.db.close()

if __name__ == ‘__main__‘:
    st = time.time()
    a = mysqlopr(ip=‘192.168.1.1‘,port = 8888,username=‘try‘,password=‘123456‘,dbname =‘trydb‘,char_set=‘utf8‘)
    a.connect()
	‘‘‘
	如果参数相同,SQL语句不同,可以现在sql_assemble方法中配置好SQL,再把参数传递进去。
	或者这边直接调用对应的方法执行
	这里过程省略
	‘‘‘
    a.close()
    et = time.time()
    logging.info("SQL executed over,cost: " + str(et -st))
    print et - st

多线程、多进程连接MySQL说明:

1、多线程连接:

起初我使用threading.thread模块,先建立一个MySQL连接,然后由多个线程来执行具体的SQL。但发现在执行的时候,不是报MySQL连接被关闭,就是出现其他异常错误。上网查询,是因为多个线程无法共享一个数据库连接,会出现不可预测的情况,官方文档说明如下:

The MySQL protocol can not handle multiple threads using the same connection at once. Some earlier versions of MySQLdb utilized locking to achieve a threadsafety of 2. While this is not terribly hard to accomplish using the standard Cursor class (which uses mysql_store_result()), it is complicated by SSCursor (which uses mysql_use_result(); with the latter you must ensure all the rows have been read before another query can be executed. It is further complicated by the addition of transactions, since transactions start when a cursor execute a query, but end when COMMIT or ROLLBACK is executed by the Connection object. Two threads simply cannot share a connection while a transaction is in progress, in addition to not being able to share it during query execution. This excessively complicated the code to the point where it just isn‘t worth it.

The general upshot of this is: Don‘t share connections between threads. It‘s really not worth your effort or mine, and in the end, will probably hurt performance, since the MySQL server runs a separate thread for each connection. You can certainly do things like cache connections in a pool, and give those connections to one thread at a time. If you let two threads use a connection simultaneously, the MySQL client library will probably upchuck and die. You have been warned.

For threaded applications, try using a connection pool. This can be done using the Pool module.

官方建议使用连接池模块,参照了他人的做法,使用DBUtils.PooledDB来创建线程连接池,一次性创建多个连接,但是查询MySQL中 连接 执行SQL语句 情况,发现也只有一个连接有在执行SQL,其他连接都是sleep状态,至今不明白为何是这情况。

2、多进程连接:

后面没辙,改用多进程(multiprocessing模块),可以和MySQL建立多个连接并发执行SQL。对比执行耗时,整体性能比单个进程快,但其中单个SQL的执行效率,多进程没有没有单进程执行的快。

demo:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import MySQLdb
from multiprocessing import Process,Pool

class mysqlopr():
    ‘‘‘省略‘‘‘

pool = Pool(5)		####设置进程数
for i in range(10):
    pool.apply_async(func=run_sql_func, args=(arg,))		####异步执行
    #pool.apply(func=run_sql_func, args=(arg,))	                ####同步执行,官方不建议使用,python3.+版本已无该方法
pool.close()
pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
时间: 2024-11-06 02:52:09

[python] 连接MySQL操作的相关文章

python连接mysql操作(1)

python连接mysql操作(1) import pymysql import pymysql.cursors # 连接数据库 connect = pymysql.Connect( host='10.10.146.28', port=3306, user='admin_m', passwd='fcfmTbRw1tz2x5L5GvjJ', db='test', charset='utf8mb4' ) def create_table(): cursor = connect.cursor() #

Python 连接 Mysql 操作异常

UserWarning: /home/toddler/.python-eggs is writable by group/others and vulnerable to attack when used with get_resource_filename. Consider a more secure location (set with .set_extraction_path or the PYTHON_EGG_CACHE environment variable). warnings.

Python连接Mysql数据库(Debian)

Python连接Mysql数据库(Debian) 以下是Python 2.*版本的安装方法,MySQL-python暂不支持Python 3.*版本 提前要做的工作: 安装setuptools,在终端中运行 wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python 安装pip,下载“get_pip.py”,运行 python get_pip.py 运行如下命令装好必要的包 sudo apt-get install python-d

python 连接mysql多层结构实例

一.python 连接mysql多层结构: 目录文件介绍: sqlexec             sql执行操作,例:增删改查 table                 数据库表模块 一个表一个模块 index.py            主文件 conf.py              数据库连接信息 目录结构如下: -rw-r--r-- 1 root root     167 Jun 22 20:36 conf.py-rw-r--r-- 1 root root     244 Jun 2

Python连接MySQL数据库之pymysql模块使用

Python连接MySQL数据库之pymysql模块使用 Python3连接MySQL PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. Django中也可以使用PyMySQL连接MySQL数据库. PyMySQL安装 pip install pymysql 连接数据库 注意事项 在进行本文以下内容之前需要注意: 你有一个MySQL数据库,并且已经启动. 你有可以连接该数据库的用户名和密码 你有一个有权限操作的datab

寒假学习进度-6(Python连接MySQL数据库)

Python连接mysql和操作 软件:pycharm 开始在pycharm下面的Terminal中安装mysql时提醒pip版本不够,所以需要先升级一下pip python -m pip install --upgrade pip 升级完pip之后就可以下载mysql pip install mysql 下载完成后在setting中查看 进行代码测试 #!/usr/bin/python # -*- coding: UTF-8 -*- import MySQLdb db =MySQLdb.con

python连接mysql数据库——版本问题

今天终于解决了使用python连接数据库不成功的问题,现将过程总结如下: 一.出现的问题 在使用python连接mysql数据库是一直出现如下问题: 1.只能连接到我数据库中的的第一个数据库,但是不能操作里面的表,会报错表不存在.(表是存在的)2.更换其他数据库后,直接报错找不到该数据库.(数据库和表均存在) 运行连接数据库的代码,会出现: conn = pymysql.connect(user='root', password='password', database='XXX') Trace

Python连接MySQL的实例代码

Python连接MySQL的实例代码 MySQLdb下载地址:http://sourceforge.net/projects/mysql-python/ 下载解压缩后放到%Python_HOME%/Lib/site-packages目录中,python会自动找到此包. MySQLdb基本上是MySQL C API的Python版,遵循Python Database API Specification v2.0. 其他: 1. 平台及版本 linux 内核2.6,gcc 3.4.4,glibc 2

[笔记]--在Ubuntu系统用Python连接Mysql数据库

环境:Ubuntu11.10,Python2.7,Mysql5.0.95 在Ubuntu终端输入命令安装Python的Mysql模块 sudo apt-get install python-mysqldb 就这么简单: 运行一下脚本: #!/usr/bin/python #-*-coding=utf-8# # import MySQLdb cn = MySQLdb.Connection(host="192.168.88.124",user="root",passwd