上一次学习了os模块,sys模块,json模块,random模块,string模块,time模块,hashlib模块,今天继续学习以下的常用模块:
1、datetime模块
2、pymysql模块(3.0以上版本)
3、Redis模块
4、flask模块
datetime模块
datetime中包含三个类date ,time,datetime
datetime.date:表示日期的类。常用的属性有year, month, day;
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond;
datetime.datetime:表示日期时间。
1、date对象由year
年份、month
月份及day
日期三部分构成:
例如:
a=datetime.date.today()#返回当前日期
print(a)
b=datetime.date(2018,3,23)#传入一个日期
print(b)
print(b.year)
print(b.month)
print(b.day)
差看执行结果:
2018-01-24
2018-03-23
2018
3
23
formattimestamp()传入一个时间戳,返回一个date对象,例如:
c=time.time()#当前时间的时间戳
d=datetime.date.fromtimestamp(c)#formtimestamp传入一个时间戳,返回一个date对象
print(d)
差看执行结果
2018-01-24
strftime格式化,例如:
e=datetime.date.today()
f=datetime.date.today().strftime('%Y%m%d')
print(e)
print(f)
查看执行结果:
20180124
timedelta加减相应的天数
print(datetime.date.today()+datetime.timedelta(3))
查看执行结果:
2018-01-27
2、time方法主要用于时间的操作,例如
print(datetime.time.max)#时间的最大值
print(datetime.time.min)#时间的最小值
print(datetime.time(12,00,59).strftime('%H:%M:%S'))#对传入的时间格式化
差看执行结果:
23:59:59.999999
00:00:00
12:00:59
3、datetime 类其实是可以看做是date
类和time
类的合体,其大部分的方法和属性都继承于这二个类,
print(datetime.datetime.today())
print(datetime.datetime.now())
print(datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S'))
print(datetime.datetime(2018,1,12,12,59,59))
查看执行结果:
2018-01-24 16:49:43.875425
2018-01-24 16:49:43.875425
2018-01-24 16:49:43
2018-01-12 12:59:59
datetime也可以直接来加减天数,例如:
a=datetime.datetime.today()+datetime.timedelta(-4)
print(a.strftime('%Y-%m-%d %H:%M:%S'))
查看执行结果:
2018-01-20 16:54:39
pymysql 模块
首先确认有没有安装pymysql模块
先导入pymysql模块。如果没有报错,则说明已经安装了pymysql;
import pymysql #导入
如果没有安装可以使用pip命令进行安装:
pip install pymysql
对数据库进行操作,我们需要进行以下操作步骤:
1、链接上mysql,使用到:IP 端口号 账号 密码 数据库名称
2、建立游标
3、执行sql
4、获取结果
实例:
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchall()
print(res)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
((5, '123', '202cb962ac59075b964b07152d234b70'), (8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (2, 'liwang', 'd123dasd8192738127398sd123'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
可以看到取出的数据为一个二维元组类型。
1、创建游标时,默认查询数据为元组类型,可以指定类型为字典类型,如下:
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchall()
print(res)
print(res[2]['id'])
cur.close()#先关闭游标
conn.close()#在关闭链接
执行查看结果:
[{'id': 5, 'username': '123', 'passwd': '202cb962ac59075b964b07152d234b70'}, {'id': 8, 'username': '1234', 'passwd': '81dc9bdb52d04dc20036dbd8313ed055'}, {'id': 7, 'username': '222', 'passwd': 'bcbe3365e6ac95ea2c0343a2395834dd'}, {'id': 6, 'username': '234', 'passwd': '289dff07669d7a23de0ef88d2f7129e7'}, {'id': 2, 'username': 'liwang', 'passwd': 'd123dasd8192738127398sd123'}, {'id': 3, 'username': 'lwwang', 'passwd': 'd1ww23dasd8192738127398sd123'}]
可以看到结果为一个list,list中是一个个字典表。如果要查看某一个字段的值,可以直接使用列表及字典的获取数据的方式来获取
2、fetch的数据类型
fetch数据类型有两种,
fetchone 只获取一条结果,他的结果放到一个一维数组中
fetchall 获取所有结果,他把结果放到一个二维元组
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchone()#只获取一条结果,他的结果放到一个一维数组
res1=cur.fetchall()#获取所有结果,是一个二维元祖,它把每一个值放到一个元祖里,每一条数据的每一个字段存到第二个元祖
print(res)
print(res1)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
(5, '123', '202cb962ac59075b964b07152d234b70')
((8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (2, 'liwang', 'd123dasd8192738127398sd123'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
我们先执行fetchall,再执行fetchone看一下:
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
tes=cur.fetchone()#指定游标类型,每一条取出的是一个字典,列名就是key值
res=cur.fetchall()#指定游标类型后,fetchall 取出的是一个list ,每个元素的值又是一个字典
print(res)
print(res1)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
((5, '123', '202cb962ac59075b964b07152d234b70'), (8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (2, 'liwang', 'd123dasd8192738127398sd123'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
None
我们看到上边的执行结果:
第二个fetchone的执行结果是空,这就与游标的位置有关了;
这就需要控制游标操作来读取数据;
3、控制游标
实例:
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchall()
cur.scroll(1,mode='absolute')
res1=cur.fetchone()
print(res)
print(res1)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
((5, '123', '202cb962ac59075b964b07152d234b70'), (8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (2, 'liwang', 'd123dasd8192738127398sd123'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
(8, '1234', '81dc9bdb52d04dc20036dbd8313ed055')
可以看到设置的1,位下标为1的位置,如果想要从头开始读取,可以设置为0;
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchall()
cur.scroll(-1,mode='relative')
res1=cur.fetchone()
print(res)
print(res1)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
((5, '123', '202cb962ac59075b964b07152d234b70'), (8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (2, 'liwang', 'd123dasd8192738127398sd123'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
(3, 'lwwang', 'd1ww23dasd8192738127398sd123')
可以看到relative模式的相对路径,设置为-1的时候,是向前移动了一个位置,如果relative模式设置为正,则是当前位置向后移动几个位置;
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
res=cur.fetchone()
res1=cur.fetchone()
print(res)
print(res1)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
(5, '123', '202cb962ac59075b964b07152d234b70')
(8, '1234', '81dc9bdb52d04dc20036dbd8313ed055')
可以看到fetch数据的时候是依次读取的,不是从头读取。读一次取一行,运行两次则是取第二条。
4、写操作的时候,如insert、update、delete 语句需要commit提交操作
import pymysql
#打开仓库大门#port 一定要写int类型
conn=pymysql.connect(host='192.168.59.60',user='root',passwd='123456',port=3306,db='txz',charset='utf8')
#建立游标,游标你的仓库管理员
cur=conn.cursor()
#执行sql
cur.execute('select * from users')
# #获取数据
sql="insert into users (username,passwd) VALUES ('lizhong','asdasd123q12aasdsd');"
cur.execute(sql)
conn.commit()
cur.execute("select * from users ;")
res=cur.fetchall()
print(res)
cur.close()#先关闭游标
conn.close()#在关闭链接
查看执行结果:
((5, '123', '202cb962ac59075b964b07152d234b70'), (8, '1234', '81dc9bdb52d04dc20036dbd8313ed055'), (7, '222', 'bcbe3365e6ac95ea2c0343a2395834dd'), (6, '234', '289dff07669d7a23de0ef88d2f7129e7'), (11, 'lifei', 'asdasd123q12aasdsd'), (9, 'lijing', 'asdasd123q12aasdsd'), (2, 'liwang', 'd123dasd8192738127398sd123'), (12, 'lizhong', 'asdasd123q12aasdsd'), (3, 'lwwang', 'd1ww23dasd8192738127398sd123'))
可以看到,插入了我们执行sql的数据;
Redis缓存数据库
要使用Redis同样需要先安装,导入,与pymysql操作类似:
pip install redis
导入Redis
import redis
我们都知道,数据库分为关系型数据库和非关系型数据库;
非关系型数据库就是nosql类型,没有库表关系,比传统的关系型数据库快,常用的nosql型数据库有:
memecache :数据存在内存里 key-value 形式
redis: 数据存在内存里,用来提高性能
MongoDB:数据存在磁盘上
对redis进行操作,可以在客户端直接操作,也可以通过python链接redis进行操作。
1、客户端操作
客户端操作可以下载redis-desktop-manager软件。
安装成功后,建立链接(要链接redis 首先保证redis服务器是运行状态。):
如果出现链接失败,的情况,如下:
需要做下面的事:
在redis.conf配置文件中,进行如下配置,
注释掉 bind 127.0.0.1
设置密码:
requirepass xxxxxxx
设置密码 为了安全一定要设,而且这里如果不绑定ip也不设密码的话,redis是默认保护模式,只能本虚拟机访问,不允许其他ip访问
保存配置文件,重启redis服务,查看虚拟机ip;
重新进行链接:链接成功
redis默认有16个DB,可以通过界面来添加相应数据:
2、python操作
通过脚本操作redis:
1、导入redis模块
2、链接redis
3、操作redis
对于关闭redis的问题,不需要手动关闭redis,
参考原因:当我们用Redis和StrictRedis创建连接时,其实内部实现并没有主动给我创建一个连接,我们获得的连接是连接池提供的连接,这个连接由连接池管理,所以我们无需关注连接是否需要主动释放的问题。另外连接池有自己的关闭连接的接口,一旦调用该接口,所有连接都将被关闭。
通过客户端我们也可以看到,redis是一个key-value存储系统,支持的value类型:string,list,set,zset(有序集合),hash(哈希类型)
我们先来创建一个redis链接:
实例:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,passwd='123456',db=3)
string类型
对redis进行操作,我们可以使用set()添加数据,get()获取数据,delete()删除数据;
如下:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
#添加数据
r.set('test','123456')
#获取数据
res=r.get('test')
print(res)
#删除数据
r.delete('test')
查看执行结果:
获取数据的结果:
b'123456'
删除数据结果:
我们看到上面获取数据的时候返回的是一个b‘123456’,属于bytes类型,在我们的日常操作中bytes类型很不方便,说以我们可以转化成字符串类型方便操作。
decode方法是将bytes类型转化成字符串类型
例如:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
#添加数据
r.set('test','123456')
#获取数据
res=r.get('test')
print(res.decode())
查看执行结果:
123456
添加数据后,我们在后台管理界面可以看到一个TTL的值是-1,这个字段是来控制失效时间的,默认的set的数据是永久有效的,如果要设置失效时间可以用setex来设置,如下:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
#添加数据
r.setex('pei_session','abcdefghijk','20')
#获取数据
res=r.get('pei_session')
print(res.decode())
查看执行结果:
abcdefghijk
查看客户端:显示TTL时间剩余9秒,超过20秒之后重新加载db3,已经找不到pei_session这条数据了:
20以后:
上面用到的set(),get(),delete(),setex()都是针对string类型的,K -V模式(redis里边的string类型);
我们常用到的redis数据类型还有hash类型
hash类型
对于hash类型的操作要使用hset(),hget(),hgetall(),例如:
hset(name,key,value):存储字典
- name:键
- key:字典的key
- value:字典的值
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
#添加数据
r.hset('user','wang','123456')
#获取数据
res=r.hget('user','wang')
print(res.decode())
查看执行结果:123456
查看客户端展示形式
当哈希表中有多条数据的时候获取出来,展示的是一个字典表:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
#获取数据
res=r.hgetall('user')
print(res)
查看执行结果
{b'li': b'123456', b'zhao': b'123456', b'wang': b'123456', b'he': b'123456'}
如果要把每一个key 和 value 都转换成字符串可以循环取值:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
redis_data=r.hgetall('user')
all_dat={}
for k,v in redis_data.items():#取出k ,v
k=k.decode()
v=v.decode()
all_dat[k]=v
print(all_dat)
查看执行结果:
{'he': '123456', 'li': '123456', 'wang': '123456', 'zhao': '123456'}
如果要添加文件夹的话可以用:来控制,例如:
import redis
#链接redis
r=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
r.set('file:log','123456')
r.set('file:img:001','001')
查看执行结果:
对hash类型的也可以建多个文件夹:
r.hset('info:user:name','wang','123456')
查看执行结果:
keys()获取所有的key值:
print(r.keys())#获取所有的key,是一个list
查看执行结果:
[b'info:user:name', b'user', b'file:log', b'file:img:001', b'test', b'file:data:ok']
可以用*通配符进行模糊查询:
print(r.keys('*user*'))
查看执行结果:
[b'info:user:name', b'user']
type()获取key的类型:
print(r.type('user'))
print(r.type('file:data:ok'))
查看执行结果:
b'hash'
b'string'
下面来做一个小程序,实现redis的数据迁移:
分析:1、需要链接两个redis
2、取出第一个redis的key,判断key的类型
3、取出redis的值,然后set进第二个redis
4、如果是hash类型的,需要再循环一次取出值
实例:
import redis
r1=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=3)
r2=redis.Redis(host='192.168.59.60',port=6379,password='123456',db=4)
ex_listkey=r1.keys()
#print(ex_listkey)
for key in ex_listkey:
if r1.type(key)==b'string':
r1_v=r1.get(key)
r2.set(key,r1_v)
elif r1.type(key)==b'hash':
r1_hash=r1.hgetall(key)
for k,v in r1_hash.items():
r2.hset(key,k,v)
else:
print('类型不考虑')
查看执行结果:
db3中的数据已经迁移到了db4中;
4、flask模块
在使用flask模块之前我们先来了解一下mock技术,
mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。
什么情况下会使用mock技术:
1、被测代码中需要依赖第三方接口返回值进行逻辑处理,可能因为网络或者其他环境因素,调用第三方经常会中断或者失败,无法对被测单元进行测试,这个时候就可以使用mock技术来将被测单元和依赖模块独立开来,使得测试可以进行下去。
2、被测单元依赖的模块尚未开发完成,而被测单元需要依赖模块的返回值进行后续处理
3、 被测单元依赖的对象较难模拟或者构造比较复杂
下面我们就用flask模块来实现。
要使用flask模块首先要安装,导入:
pip install flask
import flask#导入
Flask是一个使用 Python 编写的轻量级 Web 应用框架。可以给web前台提供后台服务。
1、获取一个类似句柄的东西app,所有的操作都要通过app来执行,通俗的说就是把当前的文件当做一个后台服务
2、设置一个简单的URL :访问路径,这个URL是提供给web前台的接口,有了接口,我们也得提供接口内容。
3、在URL下设计一个函数 def func()
4、启动整个程序 app.run(port=9999)
实例:
import pymysql
import redis
def op_mysql(host,user,passwd,db,sql,port=3306,charset='utf8'):
conn=pymysql.connect(host=host,user=user,passwd=passwd,port=port,db=db,charset=charset)
cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
cur.execute(sql)
sql_start=sql[:6].upper()
if sql_start=='SELECT':#取sql的前6位,判断它是什么类型的语句。
res=cur.fetchall()
else:
conn.commit()
res='ok'
cur.close()
conn.close()
return res
import flask
from tools import op_mysql#之前定的一个方法
import json
app=flask.Flask(__name__)
@app.route('/get_user',methods=['get','post'])
def get_alluser():
sql='select * from users'
res=op_mysql(host='192.168.1.105',user='root',passwd='123456',port=3306,db='test',sql=sql,charset='utf8')
response=json.dumps(res,ensure_ascii=False)
return response
app.run(port=8888,debug=True)
运行:
输入地址,拼接路径就可以获取到数据:
http://127.0.0.1:8888/get_user
这样就完成了一个接口的开发。
标准的程序框架设置,是下面这种形式:
说明:
为了使逻辑更清晰
一般readme文件会说明程序的使用规则,如下:
#这个程序是xxx接口
#依赖 flask pysmysql python3
#pip install flask
#pip install pymysql
#python bin/start.py
conf 文件夹下主要存放配置文件
lib 目录用来写主逻辑
bin 目录存放启动文件start.py
接下来就可以进入到程序开发阶段了~