基础环境:Python 3.5.1
mysql版本:5.6.35 (rpm安装方式)
操作系统:Centos7.3 和windows7
一、python连接数据库模块介绍:
目前主要用的有以下几种、MySQLdb和pymsql以及mysql官方提供的mysql-connector-python驱动,MySQLdb模块是python2.X使用比较多的,而python3.X使用的pymsql会更多一点,以后再研究官方的mysql-connector-python,本次学习以及实践全部基于pymsql模块。
PyMySQL的使用方法和MySQLdb几乎一样,习惯用MySQLdb的,只需 import MySQLdb 修改为 import pymysql 就可以了。
二、pymysql连接数据库的方法以及参数介绍:
pymysql连接mysql 使用pymysql.connect()方法,可以调整很多参数:
参数 |
描述 |
host | 数据库地址 |
user | 数据库用户名, |
passwd | 数据库密码,默认为空 |
db | 数据库库名,没有默认库 |
port | 数据库端口,默认3306 |
connect_timeout | 连接超时时间,秒为单位 |
use_unicode | 结果以unicode字符串返回 |
charset | 插入数据库编码 |
连接示例:
connect=pymysql.connect(host="192.168.186.157",port=3306,user="winner",passwd="123123",db="DB",charset="utf8",connect_timeout=3000)
示例连接主要包含host,user,passwrd以及port等参数
连接示例2:
connect=pymysql.connect("192.168.186.157","winner","123123","test")
不用加host等参数,但是格式固定,分别是主机 、用户、 密码以及初始连接的数据库不能互换位置,
而上面的带参数的示例相对来说更随意一些。
注意:这里的端口以及连接超时时间都是int,所以不需要带引号
连接对象返回的connect()函数:
commit() | 提交事务。对支持事务的数据库和表,如果提交修改操作,不适用这个方法,则不会写到数据库中 |
rollback() | 事务回滚。对支持事务的数据库和表,如果执行此方法,则回滚当前事务。在没有commit()前提下。 |
cursor([cursorclass]) | 创建一个游标对象。所有的sql语句的执行都要在游标对象下进行。MySQL本身不支持游标,MySQLdb模块对其游标进行了仿真。 |
在python操作mysql数据库的过程中,我们主要是使用获取游标方法counect.cursor()和cursor.execute()方法对数据库进行操作,像创建数据库以及数据表等操作,我们一般直接在mysql客户端连接,执行SQL语句就可以了,所以我们更多的操作就是增、删、改、查等操作
游标对象也提供了几种方法:
close() | 关闭游标 |
execute(sql) | 执行sql语句 |
excutemany(sql) | 执行多条sql语句 |
fetchone() | 从执行结果中取第一条记录 |
fetchmany(n) | 从执行结果中取n条记录 |
fetchall() | 从执行结果中取所有记录 |
scroll(self, value, mode='relative') | 游标滚动 |
示例一、连接192.168.186.157的mysql服务端创建pymysql库字符集为utf8
#/usr/bin/env python
#_*_coding:utf-8_*_
#导入pymysql模块
import pymysql
#使用pymysql.connect()方法创建数据库链接
con=pymysql.connect(host='192.168.186.157',user='winner',passwd='123123',port=3306)
#使用con.cursor()方法创建游标
cursor=con.cursor()
sql=" create database If Not Exists pymysql default character set utf8;"
'''sql="""create table if not exists class (id int(10) primary key auto_increment,
name varchar(20) not null ,address varchar(20) not null default "gansu")"""
'''
cursor.execute(sql)
cursor.execute("show databases")
dataname=cursor.fetchall()
print(dataname)
执行结果:
(('information_schema',), ('#mysql50#2017-03-16_09-38-47',), ('DB',), ('mysql',), ('performance_schema',),
('pymysql',), ('test',), ('winner_mas',))
Process finished with exit code 0
示例二、连接刚创建的pymysql数据库创建class表
#/usr/bin/env python
#_*_coding:utf-8_*_
#导入pymysql模块
import pymysql
#使用pymysql.connect()方法创建数据库链接
con=pymysql.connect(host='192.168.186.157',user='winner',passwd='123123',port=3306,db='pymysql')
#使用con.cursor()方法创建游标
cursor=con.cursor()
#sql=" create database If Not Exists pymysql default character set utf8;"
sql="""create table if not exists class (id int(10) primary key auto_increment,
name varchar(20) not null ,address varchar(20) not null default "gansu")"""
cursor.execute(sql)
cursor.execute("show tables")
dataname=cursor.fetchall()
print(dataname)
C:\Users\Administrator\AppData\Local\Programs\Python\Python35\python.exe C:/Users/Administrator/PycharmProjects/python/createdatabase.py
(('class',),)
C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages\pymysql\cursors.py:166: Warning: (1050, "Table 'class' already exists")
result = self._query(query)
Process finished with exit code 0
#/usr/bin/env python
#_*_coding:utf-8_*_
#导入pymysql模块
import pymysql
#打开数据库链接
connect=pymysql.connect(host="192.168.186.157",port=3306,user="winner",passwd="123123",db="pymysql",charset="utf8",connect_timeout=3000)
#使用cursor方法获取操作游标
cursor=connect.cursor()
sql=''' insert into class (name,address)
values("JSP","go"),("winner","back"),("GOOD","contine"),("cursor","execute");
'''
#使用execute方法操作数据库
cursor.execute(sql)
#事务提交
#connect.commit()
data=cursor.execute("select * from class order by id desc" )
#使用fetchall方法获取操作结果
data=cursor.fetchmany(5)
print(data)
注意:在这里将事务提交的部分注释掉了,特演示一下不提交事务的情况。
执行结果(执行第四次时):
C:\Users\Administrator\AppData\Local\Programs\Python\Python35\python.exe C:/Users/Administrator/PycharmProjects/python/insertmysql.py
((12, 'cursor', 'execute'), (11, 'GOOD', 'contine'), (10, 'winner', 'back'), (9, 'JSP', 'go'))
Process finished with exit code 0
由此我们发现数据库的事务关系在软件开发的过程当中是相当重要的一部分,所以在对事务处理的时候需要严谨。
提交事务的源代码:
#/usr/bin/env python
#_*_coding:utf-8_*_
#导入pymysql模块
import pymysql
#打开数据库链接
connect=pymysql.connect(host="192.168.186.157",port=3306,user="winner",passwd="123123",db="pymysql",charset="utf8",connect_timeout=3000)
#使用cursor方法获取操作游标
cursor=connect.cursor()
sql=''' insert into class (name,address)
values("JSP","go"),("winner","back"),("GOOD","contine"),("cursor","execute");
'''
#使用execute方法操作数据库
cursor.execute(sql)
#事务提交
connect.commit()
data=cursor.execute("select * from class order by id desc" )
#使用fetchall方法获取操作结果
data=cursor.fetchall()
print(data)
#!/usr/bin/python
#encoding=utf-8
# -*- coding:utf-8 -*-
import os
import calendar
import datetime
import MySQLdb
import os, sys, re,string
import time, tarfile,getopt
import socket
import struct
reload(sys)
sys.setdefaultencoding('utf-8')
optmap = {
'dbuser': 'tongji',
'dbpass': '64CE0CEE9A85F22C',
'dbhost': '192.168.1.10',
'dbport': 3306,
'dbname': 'web_basic'
}
code='201613'
now = int(time.time())
msgid=code+str(now)
print msgid
f = file('/home/haoren/nian/1550035_ACCOUNT_'+msgid+'_0001_V2.xml','w+')
f1 = file('/home/haoren/nian/1550035_RELATIONACCOUNTINFO_'+msgid+'_0001_V2.xml','w+')
def log(line):
line = line + "\r\n"
f.write(line)
return
def log1(line):
line = line + "\r\n"
f1.write(line)
return
def sql_select(reqsql):
try:
db_conn = MySQLdb.connect(user=optmap['dbuser'], passwd=optmap['dbpass'], host=optmap['dbhost'], port=optmap['dbport'], db=optmap['dbname'], charset='utf8')
db_cursor=db_conn.cursor()
db_conn.query("use %s"%optmap['dbname'])
count = db_cursor.execute(reqsql)
ret = db_cursor.fetchall()
db_cursor.close()
db_conn.close
return ret
except MySQLdb.Error,e:
print "Mysql ERROR %d:%s" %(e.args[0], e.args[1])
return ''
def getusercoin():
reqsql = "select * from singer_auth where status = 10 and ip !='NULL' AND (signtype = '1' OR signtype = '3') limit 150 ;"
#print reqsql
ret = sql_select(reqsql)
n = 0
for row in ret:
n += 1
if n < 100 :
print str(row[1])+','+str(row[8])
print str(row[0])
print str(row[1])
print str(row[2])
print str(row[3])
if str(row[9]).strip() == '0' and str(row[10]).strip() == '0':
print str(row[9]) +','+ str(row[10])
elif str(row[9]).strip() == '0' and str(row[10]).strip() != '0':
print str(row[9]) +','+str(row[10]).split('/')[6]
elif str(row[9]).strip() != '0' and str(row[10]).strip() == '0':
print str(row[9]).split('/')[6] +','+str(row[10])
else:
print str(row[9]).split('/')[6] +','+str(row[10]).split('/')[6]
else:
n = 0
getusercoin()
f.close()
f1.close()
#!/usr/bin/env python
#-*-coding:utf-8-*-
#明细
import MySQLdb
import os, sys, re,string
import time, tarfile,getopt
optmap = {
'dbuser' : 'haoren',
'dbpass' : 'FqDxhG4d',
'dbhost' : '192.168.1.10',
'dbport' : 3306,
'dbname' : 'JSDB'
}
def get_files(dir, pattern):
res_file_list =[]
if os.path.exists(dir):
cur_file_list = os.listdir(dir)
for file_name in cur_file_list:
if re.search(pattern, file_name):
res_file_list.append(file_name)
return res_file_list
else:
return 'no'
def main():
cur_day = time.strftime("%Y%m%d", time.localtime(time.time()-86400))
opts, args = getopt.getopt(sys.argv[1:], 'd:')
for op, value in opts:
if op == '-d':
m = re.search('[0-9]{8}', value)
if m:
cur_day = value
else:
print "请输入8位日期(比如:20130215)"
return 'no'
log_day = time.strftime('%y%m%d', time.localtime(time.mktime(time.strptime(cur_day, '%Y%m%d'))))
fmt_day = time.strftime('%Y-%m-%d', time.localtime(time.mktime(time.strptime(cur_day, '%Y%m%d'))))
print '结算统计日期:',fmt_day
#log_day = time.strftime("%y%m%d", time.localtime(time.time()-86400))
dirname="/home/haoren/logdir/%s_67"%log_day
print dirname
db_conn = MySQLdb.connect(user=optmap['dbuser'], passwd=optmap['dbpass'], host=optmap['dbhost'], port=optmap['dbport'], db=optmap['dbname'])
db_cursor=db_conn.cursor()
db_conn.query("use %s"%optmap['dbname'])
tabletime = time.strftime("%y%m%d", time.localtime(time.mktime(time.strptime(cur_day, "%Y%m%d"))))
sql="CREATE TABLE IF NOT EXISTS `JIESUANTONGJI_%s` like JIESUANTONGJISAMPLE"%tabletime
db_conn.query(sql)
db_conn.query("delete from JIESUANTONGJI_%s"%tabletime)
if os.path.exists("/tmp/JieSuanTongJi2016.txt"):
os.system("rm -f /tmp/JieSuanTongJi2016.txt")
file_list2=get_files(dirname,'billserver')
for file2 in file_list2:
command = "cat %s/%s | grep -h -w 结算统计 |grep -v 人民币消费结算统计 >> /tmp/JieSuanTongJi2016.txt"%(dirname,file2)
os.system(command)
#结算统计记录放在txt文档里面
filename='/tmp/JieSuanTongJi2016.txt'
record = {}
a_file = open(filename, 'r')
#160125-11:00:14 Bill[40268] INFO: [结算统计]时间(1453690814)类别(1)名称(购物卡收入)平台(3977962)等级(2)用户(65147500)赠送(1)个购物卡(39)给客户(65147500),客户等级(28),签约(1), 消耗人民币(100), 客户获得人民币(8000), 平台获得人民币(2000),客户当前人民币(1320960)平台当前人民币(335560)
for a_line in a_file.readlines():
m = re.search("^(\S+) Bill\[\d+\] INFO: \[结算统计\]时间\((\d+)\)类别\((\d+)\)名称\((\S+)\)平台\((\d+)\)等级\((\d+)\)用户\((\d+)\)赠送\((\d+)\)个购物卡\((\d+)\)给客户\((\d+)\),客户等级\((\d+)\),签约\((\d+)\), 消耗人民币\((\d+)\), 客户获得人民币\((\d+)\), 平台获得人民币\((\d+)\),客户当前人民币\((\d+)\)平台当前人民币\((\d+)\)", a_line)
if m:
#print "第一项:"+m.group(1)
#print "第二项:"+m.group(2)
#print "第三项:"+m.group(3)
#print "第四项:"+m.group(4)
#print "第五项:"+m.group(5)
#print "第六项:"+m.group(6)
#print "第七项:"+m.group(7)
#print "第八项:"+m.group(8)
#print "第九项:"+m.group(9)
#print "第十项:"+m.group(10)
#print "第十一项:"+m.group(11)
#print "第十二项:"+m.group(12)
#print "第十三项:"+m.group(13)
#print "第十四项:"+m.group(14)
#print "第十五项:"+m.group(15)
#print "第十六项:"+m.group(16)
#print "第十七项:"+m.group(17)
#print "第十八项:"+m.group(18)
if int(m.group(14)) >0 or int(m.group(15)) >0 :
db_conn.query("insert into JIESUANTONGJI_%s(OPTIME,TYPE,ITEMNAME,CHANNELID,CHANNELLEVEL,PRESENTERID,ITEMNUM,ITEMID,SINGERID,SINGERLEVEL,SIGN,CONSUMECOIN,SINGERRECVGOLD,CHANNELRECVGOLD,CURRENTSINGERGOLD,CURRENTCHANNELGOLD) values(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)"%(tabletime,int(m.group(2)),int(m.group(3)),str(m.group(4)),int(m.group(5)),int(m.group(6)),int(m.group(7)),int(m.group(8)),int(m.group(9)),int(m.group(10)),int(m.group(11)),int(m.group(12)),int(m.group(13)),int(m.group(14)),int(m.group(15)),int(m.group(16)),int(m.group(17))))
a_file.close()
db_conn.commit()
db_cursor.close()
db_conn.close()
main()
#if __name__ == "__main__":
# main()
由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 pymysql 模块。
pymysql 模块可以通过 pip 安装。但如果你使用的是 pycharm IDE,则可以使用 project python 安装第三方模块。
由于Python统一了数据库连接的接口,所以 pymysql 和 MySQLdb 在使用方式上是类似的:
pymysql.Connect()参数说明
host(str): MySQL服务器地址
port(int): MySQL服务器端口号
user(str): 用户名
passwd(str): 密码
db(str): 数据库名称
charset(str): 连接编码
connection对象支持的方法
cursor() 使用该连接创建并返回游标
commit() 提交当前事务
rollback() 回滚当前事务
close() 关闭连接
cursor对象支持的方法
execute(op) 执行一个数据库的查询命令
fetchone() 取得结果集的下一行
fetchmany(size) 获取结果集的下几行
fetchall() 获取结果集中的所有行
rowcount() 返回数据条数或影响行数
close() 关闭游标对象
import pymysql.cursors
# 连接数据库
connect = pymysql.Connect(
host='localhost',
port=3310,
user='woider',
passwd='3243',
db='python',
charset='utf8')
# 获取游标
cursor = connect.cursor()
# 插入数据
sql = "INSERT INTO trade (name, account, saving) VALUES ( '%s', '%s', %.2f )"data = ('雷军', '13512345678', 10000)
cursor.execute(sql % data)
connect.commit()
print('成功插入', cursor.rowcount, '条数据')
# 修改数据
sql = "UPDATE trade SET saving = %.2f WHERE account = '%s' "data = (8888, '13512345678')
cursor.execute(sql % data)
connect.commit()
print('成功修改', cursor.rowcount, '条数据')
# 查询数据
sql = "SELECT name,saving FROM trade WHERE account = '%s' "data = ('13512345678',)
cursor.execute(sql % data)
for row in cursor.fetchall():
print("Name:%s\tSaving:%.2f" % row)
print('共查找出', cursor.rowcount, '条数据')
# 删除数据
sql = "DELETE FROM trade WHERE account = '%s' LIMIT %d"data = ('13512345678', 1)
cursor.execute(sql % data)
connect.commit()
print('成功删除', cursor.rowcount, '条数据')
# 事务处理
sql_1 = "UPDATE trade SET saving = saving + 1000 WHERE account = '18012345678' "
sql_2 = "UPDATE trade SET expend = expend + 1000 WHERE account = '18012345678' "
sql_3 = "UPDATE trade SET income = income + 2000 WHERE account = '18012345678' "
try:
cursor.execute(sql_1) # 储蓄增加1000
cursor.execute(sql_2) # 支出增加1000
cursor.execute(sql_3) # 收入增加2000
except Exception as e:
connect.rollback() # 事务回滚
print('事务处理失败', e)
else:
connect.commit() # 事务提交
print('事务处理成功', cursor.rowcount)
# 关闭连接cursor.close()
connect.close()
MySQL之查询操作
import MySQLdb #必须在导入MySQLdb模块之前,要先装python操作mysql模块
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht') #这里可以理解为打开门的钥匙
cur = conn.cursor() #这里可以理解为伸出手,这里可以理解为伸出手,获取表数据
reCount = cur.execute('select * from students') #然后执行动作,只是查询影响了多少行,并不是查询相关表的数据
data = cur.fetchall() #把select查询影响到的行的数据全拿出来
cur.close() #收回手
conn.close() #关门
print reCount #输出查询影响到的行数
print data #输出查询影响到的行的数据
MySQL之插入数据
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
sql = "insert into students(id,name,sex,age,tel) values(%s,%s,%s,%s,%s)" #不管什么类型,占位符都是给%s,五个占位符,就给五个%s
params = ('6','peter','man','23','123') #如果这里id设了自增,那么这排第一位和上面一排第一位id可以不用写
reCount = cur.execute(sql,params) #插入数据
conn.commit() #提交数据,insert,update,delete都要加commit,而select则不用
cur.close() #收回手
conn.close() #关门
print reCount #输出影响到的行数
MySQL之批量插入数据
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
li = [
('wsyht11','man','26','12345'),
('wsyht12','man','26','12345'),
]
#sql = 'insert into students(name,sex,age,tel) values(%s,%s,%s,%s)'
#reCount = cur.executemany(sql,li)
reCount = cur.executemany('insert into students(name,sex,age,tel) values(%s,%s,%s,%s)',li) #插入数据
conn.commit() #提交数据,insert,update,delete都要加commit,而select则不用
cur.close() #收回手
conn.close() #关门
print reCount #输出影响到的行数
MySQL之删除数据库
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
sql = "delete from students where id=%s" #不管什么类型,占位符都是给%s,
params = (7,) #把%s需要删除的数据内容添加到params变量就可以了,如果是字符,则需要用单引号引起来如:('n1',)
reCount = cur.execute(sql,params) #删除数据
conn.commit() #提交数据,insert,update,delete都要加commit,而select则不用
cur.close() #收回手
conn.close() #关门
print reCount #输出影响到的行数
MySQL之更新数据库
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
sql = "update students set name=%s where id=6" #不管什么类型,占位符都是给%s,
params = ('wsyht90') #把id为6那一行数据中的name内容改为wsyht90
reCount = cur.execute(sql,params) #更新数据
conn.commit() #提交数据,insert,update,delete都要加commit,而select则不用
cur.close() #收回手
conn.close() #关门
print reCount #输出影响到的行数
事务,要所有提交成功才会执行成功
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
sql = "update students set age=%s where id=2"
params = (0)
reCount = cur.execute(sql,params)
sql = "update students set age=%s where id=3"
params = (46)
reCount = cur.execute(sql,params)
conn.commit()
cur.close() #收回手
conn.close() #关门
print reCount #输出影响到的行数
MySQL之批量获取字典类型数据
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
#cur = conn.cursor()
cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor) #以字典类型获取数据,也就是获取表的列名和列的数据
reCount = cur.execute('select * from students') #然后执行动作,只是查询影响了多少行,并不是查询相关表的数据
data = cur.fetchall() #把select查询影响到的行的数据全拿出来
cur.close() #收回手
conn.close() #关门
print reCount #输出查询影响到的行数
print data #输出查询影响到的行的数据
MySQL之fetchone
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
#cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
reCount = cur.execute('select * from students')
data = cur.fetchone() #只输出取到数据的第一行
print data #输出查询影响到的行的数据
#cur.scroll(0,mode='absolute') #觉对模式,往上走一层,从重输出
data = cur.fetchone() #输出取到数据的第二行
print data #输出查询影响到的行的数据
cur.scroll(-1,mode='relative') #相对模式,往上走一层,从重新输出
data = cur.fetchone() #输出取到数据的第三行
cur.close()
conn.close()
print data #输出查询影响到的行的数据
MySQL之获取自增ID
import MySQLdb
conn = MySQLdb.connect(host='192.168.1.113',user='root',passwd='123456',db='wsyht')
cur = conn.cursor()
sql = "insert into students(name,sex,age,tel) values(%s,%s,%s,%s)" #不管什么类型,占位符都是给%s,四个占位符,就给四个%s
params = ('peter','man','23','123')
reCount = cur.execute(sql,params) #插入数据
conn.commit() #提交数据,insert,update,delete都要加commit,而select则不用
new_id = cur.lastrowid #自动自增ID
print new_id #输出新的ID
#关闭连接
cur.close() #收回手
conn.close() #关门
#!/usr/bin/env Python
#coding:utf-8
import socket
def handle_request(client):
buf = client.recv(1024) #客户端接收服务端数据,缓存区1024字节,最多只能拿1024字节
client.send("HTTP/1.1 200 OK\r\n\r\n") #服务端发送信息
client.send("Hello,World!123") #服务端发送信息
print buf
def main():
sock = socket.socket() #建立socket对像
sock.bind(('localhost',5821)) #监听本地8080端口
sock.listen(5) #允许建立的最大连接数
while True:
connection, address = sock.accept() #阻塞直接有客户端请求,connectin就是客户端的socket对像,address代表客户端的地址
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
#浏览器访问测试 http://localhost:5821
#!/usr/bin/env python
#coding:utf-8
import socket
sk = socket.socket() #调用socket的这个类对像,创建对像
ip_port = ('127.0.0.1',873)
sk.bind(ip_port) #监听服务器的IP和端口
sk.listen(5) #允许的最大接数为5
while True: #创建一个死循环,让他不停的接收用户发过来的请求
conn,address = sk.accept() #阻塞等待直到有客户端连接,conn就是客户端的socket对像,address代表客户端的地址
conn.send('Hello,Wo2ld!') #向客户端发送数据
conn.close() #对客户端关闭连接
#!/usr/bin/env python
#coding:utf-8
import socket
client = socket.socket() #创建客户端socket
ip_port = ('127.0.0.1',873)
client.connect(ip_port) #连接服务端
data = client.recv(1024) #接收服务端数据
print data