zoukankan      html  css  js  c++  java
  • mysql、redis操作

    模块安装:

    数据操作用到的模块pymysql,需要通过pip install pymysql进行安装。

    redis操作用的模块是redis,需要通过pip install redis进行安装。

     检验是否安装成功:进入到Python命令行模式,输入import pymysql、 import redis ,无报错代表成功;

    mysql操作方法如下:

     查询数据:fetchone、fetchmany(n)、fetchall()
    import pymysql
    #建立mysql连接,ip、端口、用户名、密码(passwd,不能写成其他,例如:pwd或者p,否则报错)、库名
    conn = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='szz', port=3306, charset='utf8')
    #创建游标
    cur = conn.cursor(cursor=pymysql.cursors.DictCursor)  #指定cursor的类型为字典,返回结果类型是字典,不再是元组
    #执行sql,返回值是int,查询出来的结果有几条
    cur.execute('select * from test')
    #获取第一条数据,游标cur所在的位置为1,游标从0开始,查询结果类型为:字典
    row_1 = cur.fetchone()
    cur.scroll(0, mode='absolute')   #将游标移动到初始位置
    #获取前n行数据
    row_2 = cur.fetchmany(n)
    cur.scroll(0, mode='absolute')   #将游标移动到初始位置
    #获取所有数据,返回结果类型是:list,里面元素是字典
    row_3 = cur.fetchall()
    cur.scroll(0, mode='absolute')   #将游标移动到初始位置
    print(row_2)
    #关闭游标
    cur.close()
    #关闭连接
    conn.close()

    增加、更新、删除数据:

    import pymysql
    #建立mysql连接
    conn = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='szz', port=3306, charset='utf8')
    #创建游标
    cur = conn.cursor(cursor=pymysql.cursors.DictCursor)  #指定cursor的类型为字典,返回结果类型是字典,不再是元组
    #执行sql
    sql = 'insert into test values(5, "断点", "e10adc3949ba59abbe56e057f20f883e")'
    sql_update = 'update test set name="薛之谦" where id=2 '
    sql_del = 'delete from test where id = 3'
    cur.execute(sql_del)
    #insert、update、delete语句需要进行commit,否则无法保证修改或者新建的数据
    conn.commit()
    #关闭游标
    cur.close()
    #关闭连接
    conn.close()

    cursor的相对、绝对位置移动

    import pymysql
    #建立mysql连接
    conn = pymysql.connect(host='192.168.3.66', user='root', passwd='123456', db='szz', port=3306, charset='utf8')
    #创建游标
    cur = conn.cursor(cursor=pymysql.cursors.DictCursor)  #指定cursor的类型为字典,返回结果类型是字典,不再是元组
    num = cur.execute('select * from testlhl')
    print(num)                                           #返回结果是int类型
    
    row_1 = cur.fetchone()             # 此时游标的位置在1,数据库取值从0下标开始,获取数据库第一条数据
    cur.scroll(2, mode='absolute')     #absolute绝对位置,直接是将游标从0位置移动到指定的位置2
    row_2 = cur.fetchone()             #读取数据库第3条数据,游标在3位置
    cur.scroll(2, mode='relative')     #relative相对位置,相对于游标当前所在位置,进行移动,移动1位,游标在4位置,若相对移动的位置超过下标,则报out of range
    row_3 = cur.fetchone()             #读取第5条数据
    #关闭游标
    cur.close()
    #关闭连接
    conn.close()

     mysql的增删改查公共方法,代码如下:

     1 def getconn(host, user, passwd, db, sql, port=3306,charset='utf8'):
     2     conn = pymysql.connect(host=host, user=user, passwd=passwd, port=port, db=db, charset=charset)  #建立连接
     3     cur = conn.cursor(cursor=pymysql.cursors.DictCursor)        #建立游标并指定游标类型
     4     cur.execute(sql)                                            #执行sql
     5     if sql.startswith('select'):                                #判断sql是否是select
     6         res = cur.fetchone()
     7     else:
     8         conn.commit()                                           #insertdeleteupdate语句执行完毕后需要进行commit
    9 res = 88 10 cur.close() #关闭游标 11 conn.close() #关闭连接 12 return res

    redis操作方法如下:

    key的类型是string,进行set操作,模式{key, value},如下:

    import redis
    db = 0
    #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
    conn_redis = redis.Redis(host='127.0.0.1', port=6379, password='123456', db=db)
    #给redis添加值,传值方式是key-value,key不可重复,value的形式尽量是string,也可以传list、字典,redis内存放的是字节res = conn_redis.set('name', 'testredis')
    #print(res)    #返回值是布尔类型,set成功,则返回true
    conn_redis.set('days', '[10,4,5,12,44]')
    
    #set key值到redis内,且可以设置过期时间,10s result = conn_redis.setex('session', 'abcder1233@sdfrr', 10) #单位是s print(result) #返回值是布尔类型,set成功,则返回true
    #批量插入redis,可以写入多个key-valye
    conn_redis.mset(a='xiaohei', b='xiaobai', c='xiaohuang')
    #设置key时,可以设置文件夹,user文件夹,key:test,value:haha
    conn_redis.set('user:test','haha')

    获取redis内的数据,通过key值进行获取:

     1 import redis
     2 import json
     3 db = 0
     4 #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
     5 conn_redis = redis.Redis(host='127.0.0.1', port=6379, password='123456', db=db)
     6 #获取redis的值,返回结果类型是bytes
     7 res = conn_redis.get('abcd')
     8 #使用decode()将bytes类型转换为字符串:输出>>>>>testredis
     9 new_res = res.decode()
    10 #使用json的loads,将json串(字符串)转换为字典
    11 dic_res = json.loads(new_res)
    12 
    13 #获取不存在的key,返回结果为None
    14 res1 = conn_redis.get('asdfg')
    15 print(res1.decode())       #输出>>>>>>'NoneType' object has no attribute 'decode'
    16 
    17 #获取所有的keys,且循环遍历进行输入,使用decode()转换为字符串
    18 list_keys = conn_redis.keys()
    19 for key in list_keys:
    20     print(key.decode())
    21 
    22 #获取所有的key中以n开头的key,返回结果类型是list,元素类型是bytes  输出>>>>>[b'nbeee', b'name', b'nest']
    23 print(conn_redis.keys('n*'))

    删除redis内的值,通过key删除:

    import redis
    db = 0
    #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
    conn_redis = redis.Redis(host='192.168.3.66', port=6379, password='123456', db=db)
    #删除存在的key,删除key后,redis内不存在该key,返回结果为1,删除了一个key
    res = conn_redis.delete('a')
    #删除不存在的key,返回结果为0,没有删除key
    res1 = conn_redis.delete('d')
    #删除多个key,返回结果n, 删除了几个key就返回数字几
    asdf = conn_redis.delete('a', 'b', 'c')
    print(asdf)

    key的类型是hash,进行set操作,模式:{key,{key1,value}}如下:

    import redis
    db = 0
    #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
    conn_redis = redis.Redis(host='192.168.3.66', port=6379, password='123456', db=db)
    #hash类型的key,模式{name,{key,value}},里面key不能重复,返回值为int
    res = conn_redis.hset('user_session', 'lhl', 'sunny')
    #hash类型的key,添加值时也可以设置文件夹
    conn_redis.hset('session:redis_test', 'age', 18) 

    key的类型是hash,进行get操作,如下:

    import redis
    db = 0
    #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
    conn_redis = redis.Redis(host='192.168.3.66', port=6379, password='123456', db=db)
    #获取hash类型中的某个name下的某个key对应的value ,获取指定name里面的key的值,返回结果类似是bytes
    res = conn_redis.hget('user_session', 'week')
    #获取hash类型中name里面所有的key,返回结果是字典>>>>>输出:{b'test': b'sunny', b'week': b'sunny'}
    all = conn_redis.hgetall('user_session')

    key的类型是hash,进行delete操作,如下:

    import redis
    db = 0
    #连接redis,password不简写(否则或报错),db若不写,则默认操作db0
    conn_redis = redis.Redis(host='192.168.3.66', port=6379, password='123456', db=db)
    #hash类型的key,删除整个key, delete(name),返回结果为1
    res = conn_redis.delete('user_session')
    #hash类型的key,删除指定name里的key,若删除的key或者name不存在,则返回0
    res = conn_redis.hdel('user_session', 'week')

    redis的set、get公共操作方法如下:

    1 def opRedis(host, password, key, value=None, port=6379,db=0):      #redis操作时需要传入keyvalue
    2     conn_redis = redis.Redis(host=host, password=password, port=port, db=db)   #获取redis连接
    3     if value:                           #判断value是否传值,如果不为None,则是set
    4         conn_redis.setex(key, value, 60)   #设置key的过期时间,60s
    5         res = 88
    6     else:
    7         res = conn_redis.get(key).decode()     #将从redis内读取的值,由bytes转换为字符串
    8     return res

    redis-hash类型的set、get公共操作方法:

     1 #对hash类型的数据进行set、get操作
     2 def get_hashall(name,key=None,value=None):
     3     conn = getredisConn()
     4     #判断key和value是否为空。不为空则是对redis进行set值, 数据模式{name:{key,value}}
     5     if key and value:
     6         conn.hset(name, key, value)
     7     else:
     8         # 获hash类型的所有name对应的值,返回结果是字典类型{key:value, key:value},里面元素类型是bytes
     9         res = conn.hgetall(name)
    10         return res
    11 
    12 if __name__ == '__main__':
    13     res = get_hashall('sites')
    14     print(res)   #输出:{b'zidonghua': b'http://www.baidu.com', b'mayijinfu': b'http://www.baidu.com', b'meicai': b'http://www.baidu.com', b'12asdf': b'http://www.baidu.com'}
    15     for k, v in res.items():
    16         new_k = k.decode()
    17         new_v = v.decode()
    18         print(new_k, new_v)

    场景1:

      公司服务器最近要扩容,现对数据库进行迁移。测试需要进行数据库对比测试,校验迁移后的表结构、数据是否一致

    dic = {
        "host": '192.168.200.3',
        'user': 'mjyx_rw',
        'password': 'meijia@123',
        'port': 6033,
        'db': 'mjyx_product'
    }
    
    #mysql 操作
    def op_mysql( sql, res_many=False):
        con = pymysql.connect(host=dic['host'], user=dic['user'], password=dic['password'], db=dic['db'], port=dic['port'], charset='utf8', autocommit=True)
        cur = con.cursor(pymysql.cursors.DictCursor)
        cur.execute(sql)
        if res_many:
            res = cur.fetchall()
        else:
            res = cur.fetchone()
        cur.close()
        con.close()
        return res
    
    def table_diff(table1,table2):
        sql1 = 'select * from {0};'.format(table1)
        sql2 = 'select * from {0};'.format(table2)
    
        res_data1 = op_mysql(sql1, res_many=True)  #返回结果是list [{},{}]
        res_data2 = op_mysql(sql2, res_many=True)
    
        #需求1,只是对比数据是否一致
        str_old = ''
        for line in res_data1:
            for k, v in line.items():
                str_old += str(v)
        md_old = hashlib.md5(str_old.encode())
        res_old = md_old.hexdigest()
    
        str_new = ''
        for line in res_data2:
            for k, v in line.items():
                str_new += str(v)
        md_new = hashlib.md5(str_new.encode())
        res_new = md_new.hexdigest()
    
        if res_old == res_new:
            return True
        else:
            print('表结构不一致')
    
    
    res = table_diff('xxx_label', 'xxx_label_new')
    print(res)

    场景2: 

      对比数据库表结构、数据,并找出不一致的数据

    '''
    1. 表1取出所有数据,返回list [{},{}]
    2. 循环list,取出每行数据,获取唯一标识id
    3. 表2根据唯一标识id,获取每行数据
    4. 分别循环每行数据,获取每行数据的value,然后加密
    5.进行对比,判断加密后的结果是否一致
    '''
    
    def t_diff(table1,table2):
    
        sql1 = 'select * from {0};'.format(table1)
        res_data1 = op_mysql(sql1, res_many=True)  # 返回结果是list [{},{}]
    
        for index, line in enumerate(res_data1):
            str_res = ''
            id = line.get('pk_label')  # 取出每行数据的id
            for k,v in line.items():
                str_res += str(v)
    
            md_old = hashlib.md5(str_res.encode())
            res_old = md_old.hexdigest()
    
            str_res2 = ''
            sql2 = 'select * from {0} where pk_label = {1}'.format(table2, id)   #表2,根据id取出每行数据
            res_data2 = op_mysql(sql2)
            for k1, v1 in res_data2.items():
                str_res2 += str(v1)
    
            md_new = hashlib.md5(str_res2.encode())
            res_new = md_new.hexdigest()
    
            if res_old != res_new:
                print('第%d行数据内容%s与数据内容不一致%s' % (id, str_res, str_res2))
    
    t_diff('xx_label', 'xx_label_new')

    有写的不对的,或者不明白的,欢迎留言~~~~

  • 相关阅读:
    next_permutation函数(全排列)
    滚动数组
    多重背包问题
    ubuntu12.04硬盘安装
    UBUNTU12.04下安装配置体验gnome3
    给Ubuntu安装KDE桌面 [转]
    Ubuntu 13.04 用户安装 gnome 3.8 桌面
    ubuntu下安装wine
    ubuntu 安装输入法(fcitx)
    js 对url进行编码和解码的三种方式
  • 原文地址:https://www.cnblogs.com/lhly/p/7082206.html
Copyright © 2011-2022 走看看