Redis和MySQL命令封装,连接池以及特殊场景下的封装

由于项目需求以及模块化的需要,此次初版中简单实现了MySQL的封装的升级版,和redis与MySQL的互动,不是很成熟先写出来慢慢改。

配置:

import hashlib
import redis
import pymysql
import time
import json
from DBUtils.PooledDB import PooledDB
"""
利用redis的集合不允许添加重复元素来进行去重
"""
b = {"user": "root",
     "passwd": "Lohas123",
     "host": "121.40.52.101",
     "db": 'price',
     "port": 3306,
     "charset": 'utf8'
     }
class Sql_all:
    __mysql_pool=None
    __redis=None
    #redis连接池初始化配置,此处各位同仁一定注意游标和连接不能全局化,否则全局就一个连接并且一旦释放程序就会报错
    def __init__(self):
        self.re_con=Sql_all.getredisconn()


    # sql连接池
    @staticmethod
    def getmysqlconn():
        if Sql_all.__mysql_pool is None:
            __mysql_pool = PooledDB(creator=pymysql, mincached=3, maxcached=20, host=b["host"], user=b["user"],
                              passwd=b["passwd"], db=b["db"], port=b["port"], charset=b["charset"])
        return __mysql_pool.connection()
    #redis
    @staticmethod
    def getredisconn():
        if Sql_all.__redis is None:
            r= redis.ConnectionPool(host='121.43.198.91', port=6379, db=0,password='Lohas3520')#,password='Lohas3520'
            __redis_pool = redis.StrictRedis(connection_pool=r)
        return __redis_pool

MySQL封装

#Mysql insert/update/delete
    def mysql_insert(self, sql='',value=(),insert_statue=1,_id=None):
        """
        实现数据库insert/update/delete
        :param _id就是在只插入一个的情况下返回一个id并改变_id值,不用传值默认None,
        :param insert_statue: 插入状态int值,1为单词插入一个,2为插入多个值,三或以上为删除或修改模式,默认为1
        :param sql: 插入的sql格式
        :param value: 当插入一个值时为tuple/list,多个值时为tuple(tuple)/list[list],非插入状态下value可为()
        :return:
        """
        my_coon = Sql_all.getmysqlconn()
        my_cur = my_coon.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            print('op_insert',sql)
            if insert_statue==1:
                my_cur.execute(sql,value)
                _id = my_cur.lastrowid#获取插入的id
            elif insert_statue==2:
                my_cur.executemany(sql,value)
            else:
                my_cur.execute(sql, value)
            print("修改中")
            my_coon.commit()
            print("修改成功")
            self.dispose(my_coon,my_cur)
            if _id == 0:
                return True
            return True,_id
        except Exception as e:
            print(e)
            my_coon.rollback()
            self.dispose(my_coon,my_cur)
            print("修改失败请检查sql语句")
            return 0
    #Mysql查询
    def mysql_select(self,sql='',select_satue=2,num=None,param=None):
        """
        实现MySQL数据库取的功能
        :param sql:sql查询语句如有体条件,把条件传入param
        :param param:可选参数,条件列表值(元祖/列表),默认None
        :param num:当只需要查询一部分时候,默认None
        :param select_satue,可选状态int类型(或能被转成int得值),1为查询一条,2为查询所有,
                3或其他为查询一部分(三种状态都是在指定条件下返回的数量)此时需传入参数num,默认2查询所有
        :return:
        """
        #必须每次重连并释放,否则数据库会异常的阻塞导致程序无法进行
        my_coon = Sql_all.getmysqlconn()
        my_cur = my_coon.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            if param == None:
                count=int(my_cur.execute(sql))  # 执行sql
            else:
                count =int(my_cur.execute(sql,param))
            # print(count)
            #此处count》0即为查找到值
            if count >0:
                # print(count)
                if int(select_satue)==2:
                    select_res = my_cur.fetchall()# 返回结果为字典
                elif int(select_satue)==1:
                    select_res=my_cur.fetchone()
                else:
                    select_res=my_cur.fetchmany(num)
            else:
                select_res=False

            print("查询成功")
            self.dispose(my_coon,my_cur)
            return select_res
        except Exception as e:
            print('select except ',e)
            self.dispose(my_coon,my_cur)
            print("查询失败请检查sql语句")
            return None

    def dispose(self,my_coon,my_cur):
        my_coon.close()
        my_cur.close()

redis操作

#redis压缩url
    def compressed(self,value):
        sha1obj = hashlib.sha1()
        sha1obj.update(value.encode('utf-8'))
        hash_value = sha1obj.hexdigest()
        return hash_value

    #redis操作(需要被管道监控的前提),0模式为长度对比去重(利用redis管道特性
          锁住url或关键字进行去重,在把数据持久化到MySQL),1模式为分页计数
          (先利用redis管道锁住page在用MySQL分页)
        def redis_operation(self,key,sql_statue,value=None):
        """
        :param sql_statue操作redis的模式
        :param r:redis连接
        :param value:add的数据或者添加的页码数,先压缩在添加
        :param key:项目所使用的集合名称,建议如下格式:”projectname:task_remove_repeate“
        :return:
        """

        # while True:
        try:
            pipe = self.getredisconn().pipeline()
            pipe.watch(key)
            # 开启事务
            pipe.multi()
            #去重模式,长度对比去重
            if sql_statue==0:
                hash_value = self.compressed(value)
                long_1 = self.re_con.scard(key)
                self.re_con.sadd(key, hash_value)
                long_2 = self.re_con.scard(key)
                return long_1,long_2
            #翻页模式
            elif sql_statue==1:
                pageindex=int(self.re_con.get(key))
                pageindex += 10
                self.re_con.set(key,pageindex)
                return pageindex
        except Exception as e:
            print("redis报错了:",e)
    #添加到redis中,数据需要去重的情况使用set比较好
    #def add_redis(self,url, set_name,r=None):
       # r.sadd(set_name,url)

redis数据到MySQL

    #实时取数据到mysql,超过30分钟退出(此状态是数据下载完毕才会有)这个要写到爬虫中去。还没想好如何和上面insert部分结合
    def redis_put(self,key):
        num=0
        while True:
            if num>=600:
                break
            if self.re_con.scard(key)>0:
                num=0
                h =self.re_con.spop(key)
                try:
                    result=json.loads(str(h,encoding='utf-8').replace("'", "\""))
                except Exception as e:
                    print(e)
                    self.error_file(h)
                    continue
            else:
                num+=1
                time.sleep(5)

    # #上文json.loads()处理时未明原因报错,此错误线下实验无问题,此处处理异常跳过,收集出错项。###错误待考证
    def error_file(self,h):
        with open('elong_error_file.txt','w',encoding="utf-8") as f:
            f.write(str(h,encoding='utf-8').replace("'", "\""))

    def redis_close(self,pool):
        """
        释放redis连接池
        :param pool:
        :return:
        """
        pool.disconnect()

由于此篇文章还没写完,目标了也是封装程一个sql组件,当然可能会有些鸡肋,毕竟还有ORM 这个东西,在加上实际上很多东西是已有的,此处了只是想看能不能满足工作需求。不完善的地方请多多指教

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值