1. 程式人生 > >將mysql資料庫中的單個庫的資料同步到redis資料庫中

將mysql資料庫中的單個庫的資料同步到redis資料庫中

實際程式碼只有一點,其他的為備忘

# -*- coding:utf-8 -*-
import MySQLdb
import redis

class Config:
    def __init__(self):
        self.mysql_host = '192.168.44.60'
        self.mysql_user = 'root'
        self.mysql_port = 3306
        self.mysql_password = '123456'
        self.mysql_db = 'bamboo'
        self.mysql_charset = 'utf8'
        self.mysql_show_tables = "show tables"
        self.mysql_desc_table = "desc %s"
        self.mysql_query_info = "select * from  %s"

        self.redis_host = "192.168.44.60"
        self.redis_port = 6379
        self.redis_passwd = 123456
        self.redis_db = 0

config = Config()

class MySQLHelper:
    myVersion = 0.1

    def __init__(self):
        self.host = config.mysql_host
        self.user = config.mysql_user
        self.password = config.mysql_password
        self.charset = config.mysql_charset
        self.db = config.mysql_db
        try:
            self.conn = MySQLdb.connect(host=self.host, user=self.user, passwd=self.password,db=self.db,charset=self.charset)
            self.cursor = self.conn.cursor()
        except MySQLdb.Error as e:
            print ('MySql Error : %d %s' % (e.args[0], e.args[1]))

    def query(self, sql):
        try:

            cursor = self.cursor
            cursor.execute(sql)
            return cursor
        except MySQLdb.Error as e:
            print('MySql Error: %s SQL: %s' % (e, sql))

    def queryOnlyRow(self, sql):
        try:
            cursor = self.query(sql)
            result = cursor.fetchall()
            desc = cursor.description

            row = {}
            for i in range(0, len(result)):
                row[desc[i][0]] = result[i]
            return row
        except MySQLdb.Error as e:
            print('MySql Error: %s SQL: %s' % (e, sql))

    def queryAll(self, sql):
        try:

            cursor = self.query(sql)
            result = cursor.fetchall()

            desc = cursor.description
            rows = []
            for cloumn in result:
                row = {}
                for i in range(0, len(cloumn)):
                    row[desc[i][0]] = cloumn[i]
                rows.append(row)
            return rows

        except MySQLdb.Error as e:
            print('MySql Error: %s SQL: %s' % (e, sql))

    def queryTableNums(self,sql):
        try:
            cursor = self.query(sql)
            result = cursor.fetchall()
            row = []
            for cloumn in result:
                row.append(cloumn[0])
            return row

        except MySQLdb.Error as e:
            print('Mysql Error: %s SQL: %s' %(e,sql))

    def insert(self, tableName, pData):
        try:
            newData = {}
            for key in pData:
                newData[key] = "'" + str(pData[key]) + "'"
            key = ','.join(newData.keys())
            value = ','.join(map(str,newData.values()))
            sql = "insert into " + tableName + "(" + key + ") values(" + value + ")"
            self.query("set names 'utf8'")
            self.query(sql)
            self.commit()
        except MySQLdb.Error as e:
            self.conn.rollback()
            print('MySql Error: %s %s' % (e.args[0], e.args[1]))

    def update(self, tableName, pData, whereData):
        try:
            newData = []
            keys = pData.keys()
            for i in keys:
                item = "%s=%s" % (i, "'" + pData[i] + "'")
                newData.append(item)
            items = ','.join(newData)
            newData2 = []
            keys = whereData.keys()
            for i in keys:
                item = "%s=%s" % (i, "'" + whereData[i] + "'")
                newData2.append(item)
            whereItems = " AND ".join(newData2)
            sql = "update " + tableName + " set " + items + " where " + whereItems
            self.query("set names 'utf8'")
            self.query(sql)
            self.commit()
        except MySQLdb.Error as e:
            self.conn.rollback()
            print('MySql Error: %s %s' % (e.args[0], e.args[1]))

    def getLastInsertRowId(self):
        return self.cursor.lastrowid

    def getRowCount(self):
        return self.cursor.rowcount

    def commit(self):
        self.conn.commit()

    def close(self):
        self.cursor.close()
        self.conn.close()

class RedisHelper():

    __redis_instance = None

    def __init__(self):
        self.host = config.redis_host
        self.port = config.redis_port
        self.passwd = config.redis_passwd
        self.db = config.redis_db
        try:
            self.connPoor = redis.ConnectionPool(host=self.host,port=self.port,db=self.db,password=self.passwd)
            self.rd = redis.Redis(connection_pool=self.connPoor)
        except redis.DataError as e:
            print('Redis Error : %d %s' % (e.args[0], e.args[1]))

    @staticmethod
    def getObj():
        if RedisHelper.__redis_instance:
            return RedisHelper.__redis_instance
        else:
            RedisHelper.__redis_instance = RedisHelper().rd
            return RedisHelper.__redis_instance

    # string 操作

    def setkey(self,key,value,**kwargs):
        """
        set(name, value, ex=None, px=None, nx=False, xx=False)
        :param key: 鍵
        :param value: 值
        :param kwargs:
            在Redis中設定值,預設,不存在則建立,存在則修改
            引數:
            ex,過期時間(秒)
            px,過期時間(毫秒)
            nx,如果設定為True,則只有name不存在時,當前set操作才執行
            xx,如果設定為True,則只有name存在時,當前set操作才執行
        :return: True or False
        """
        res = self.rd.set(key,value,**kwargs)

        return res

    def getkey(self,key):
        return self.rd.get(key)

    def setnxkey(self,key,value):
        """
        :param key:
        :param value:
        :return: True or False
        設定值,只有key不存在時,執行設定操作(新增)
        """
        return self.rd.setnx(key,value)

    def setexkey(self,key,value,time=5):
        """
        :param key:
        :param value:
        :param time: 過期時間 (秒 或 timedelta物件)
        :return: True or False
        """
        return self.rd.setex(key,time,value)

    def psetexkey(self,key,value,time):
        """
        :param key:
        :param value:
        :param time: time_ms,過期時間(數字毫秒 或 timedelta物件)
        :return:
        """
        return self.rd.psetex(key,time,value)

    def msetkey(self,mapping):
        """
        批量設定多個值
        :param mapping: {'k1':'v1','k2':'v2'} or k1='v1',k2='v2'
        :return:
        """
        return self.rd.mset(mapping)

    def mgetkey(self,keys,*args):
        """
        批量獲取多個值
        'k1','k2' or ['k1','k2']
        :param keys:
        :param args:
        :return:
        """
        return self.rd.mget(keys,args)

    def getsetkey(self,key,value):
        """
        獲取值並設定新值
        :param key:
        :param value:
        :return:
        """
        return self.rd.getset(key,value)

    def getrangekey(self,key,start,end):
        """
        獲取子序列(根據位元組獲取,非字元) 一個漢字,是佔3個位元組
        :param key:
        :param start: bytes 起始位置(包含)
        :param end: bytes  結束位置(包含)
        :return:
        set 'name' 'helloworld'
        OK
        GETRANGE 'name' 0 2
        "hel"
        getrange 'name' 0 -1
        "helloworld"
        """
        return self.rd.getrange(key,start,end)

    def setrange(self,key,index,value):
        """
        修改字串內容,從指定字串索引開始向後替換(新值太長時,則向後新增)
        引數:

        :param key:
        :param index: 字串的索引,位元組(一個漢字三個位元組)
        :param value: 要設定的值
        :return:
        """
        return self.rd.setrange(key,index,value)

    def strlenkey(self,key):
        """
        返回name對應值的位元組長度(一個漢字3個位元組)
        :param key:
        :return:
        """
        return self.rd.strlen(key)

    def incrkey(self,key):
        """
        自增 name對應的值,當name不存在時,則建立name=amount,否則,則自增。
        :param key:
        :param amount: 自增數 必須是整數 一次只能自增一個
        :return:
        """

        return self.rd.incr(key,1)

    def incrbykey(self,key,amount=1):
        """
        自增 key對應的值,當key不存在時,則建立key=amount,否則,則自增。
        :param key:
        :param amount: 自增數 必須是整數
        :return:
        """
        try:
            if not isinstance(amount,int):
                raise TypeError('amount 必須是整數')
            return self.rd.incrby(key,amount)
        except Exception as e:
            return "Func incrbykey Error : %d %s" % (e.args[0], e.args[1])

    def incrbyfloatkey(self,key,amount=1.0):
        """
        自增 key對應的值,當key不存在時,則建立key=amount,否則,則自增。
        :param key:
        :param amount: 自增數(浮點型)
        :return:
        """
        try:
            if not isinstance(amount,float):
                raise TypeError('amount 必須是浮點數')
            return self.rd.incrbyfloat(key,amount)
        except Exception as e:
            return "Func incrbyfloatkey Error : %d %s" % (e.args[0], e.args[1])

    def decrkey(self,key):
        """
        自減 name對應的值,當name不存在時,則建立name=amount,否則,則自減
        :param name:
        :return:
        """
        self.rd.decr(key,1)

    def decrbykey(self,key,amount=1):
        """
        自減 key對應的值,當key不存在時,則建立key=amount,否則,則自減。
        :param key:
        :param amount: 自減數 必須是整數
        :return:
        """
        try:
            if not isinstance(amount, int):
                raise TypeError('amount 必須是整數')
            return self.rd.decrby(key, amount)
        except Exception as e:
            return "Func decrbykey Error : %d %s" % (e.args[0], e.args[1])

    def appendkey(self,key,value):
        """
        在redis key對應的值後面追加內容
        :param key:
        :param value: 要追加的字串
        :return:
        """
        return self.rd.append(key,value)

    def setbitkey(self,key,index,value):
        """
        注:如果在Redis中有一個對應: n1 = "foo",
        那麼字串foo的二進位制表示為:01100110 01101111 01101111
        所以,如果執行 setbit('n1', 7, 1),則就會將第7位設定為1,
        那麼最終二進位制則變成 01100111 01101111 01101111,即:"goo"

        擴充套件,轉換二進位制表示:
        source = "陳思維"
        source = "foo"
        for i in source:
        num = ord(i)
        print bin(num).replace('b','')
        特別的,如果source是漢字 "陳思維"怎麼辦?
        答:對於utf-8,每一個漢字佔 3 個位元組,那麼 "陳思維" 則有 9個位元組
        對於漢字,for迴圈時候會按照 位元組 迭代,那麼在迭代時,將每一個位元組轉換 十進位制數,然後再將十進位制數轉換成二進位制
        11100110 10101101 10100110 11100110 10110010 10011011 11101001 10111101 10010000

        對name對應值的二進位制表示的位進行操作
        :param key:
        :param index: 位的索引(將值變換成二進位制後再進行索引)
        :param value: 值只能是 1 或 0
        :return:
        """
        try:
            if not isinstance(index,int):
                raise TypeError('index 只能是數字')
            if  value not in [0,1]:
                raise ValueError('value 只能是0或1' )

            return self.rd.setbit(key,index,value)

        except Exception as e:
            return "Redis Error : %d %s" % (e.args[0], e.args[1])

    def getbitkey(self,key,index):
        """
        獲取name對應的值的二進位制表示中的某位的值 (0或1)
        :param key:
        :param index: 0 or 1
        :return:
        """
        try:
            if index not in [0,1]:
                raise ValueError("index 值只能是0或1")
            return self.rd.getbit(key,index)
        except Exception as e:
            return "Redis Error : %d %s" % (e.args[0], e.args[1])

    def bitcountkey(self,key,start=None,end=None):
        """
        獲取name對應的值的二進位制表示中 1 的個數
        :param key:
        :param start:
        :param end:
        :return:
        """
        return self.rd.bitcount(key,start,end)

    def bitopkey(self,operation,new_key,*keys):
        """
        bitop("AND", 'new_name', 'n1', 'n2', 'n3')
        獲取Redis中n1,n2,n3對應的值,然後講所有的值做位運算(求並集),然後將結果儲存 new_name 對應的值中
        r.set("foo","1")  # 0110001
        r.set("foo1","2")  # 0110010
        print(r.mget("foo","foo1"))  # ['goo1', 'baaanew']
        print(r.bitop("AND","new","foo","foo1"))  # "new" 0 0110000
        print(r.mget("foo","foo1","new"))

        source = "12"
        for i in source:
        num = ord(i)
        print(num)  # 列印每個字母字元或者漢字字元對應的ascii碼值 f-102-0b100111-01100111
        print(bin(num))  # 列印每個10進位制ascii碼值轉換成二進位制的值 0b1100110(0b表示二進位制)
        print bin(num).replace('b','')  # 將二進位制0b1100110替換成01100110

        獲取多個值,並將值做位運算,將最後的結果儲存至新的name對應的值
        :param operation: AND(並) 、 OR(或) 、 NOT(非) 、 XOR(異或)
        :param new_key: new key
        :param keys: 要查詢的Redis的name
        :return:
        """
        return self.rd.bitop(operation,new_key,keys)

    # hash 操作

    def hsetkey(self,name,key,value):
        """
        name對應的hash中設定一個鍵值對(不存在,則建立;否則,修改)

        :param name: redis的name
        :param key: name對應的hash中的key
        :param value: name對應的hash中的value
        :return:
        """
        return self.rd.hset(name,key,value)

    def hmsetkey(self,name,mapping):
        """
        在name對應的hash中批量設定鍵值對
        :param name:
        :param mapping: {'k1':'v1','k2':'v2'}
        :return:
        """
        return self.rd.hmset(name,mapping)

    def hgetkey(self,name,key):
        """
        在name對應的hash中獲取根據key獲取value
        :param name:
        :param key:
        :return:
        """
        return self.rd.hget(name,key)

    def hgetallkey(self,name):
        """
        獲取hash中對應name的所有值
        :param name:
        :return:
        """
        return self.rd.hgetall(name)

    def hmgetkey(self,name,keys,*args):
        """
        在name對應的hash中獲取多個key的值
        :param name:
        :param keys: ['k1','k2','k3']
        :param args: 'k1','k2','k3'
        :return:
        """
        return self.rd.hmget(name,keys,args)

    def hlenkey(self,name):
        """
        獲取name對應的hash中的鍵值對的個數
        :param name:
        :return:
        """
        return self.rd.hlen(name)

    def hallkeys(self,name):
        """
        獲取name對應的hash中所有的key的值
        :param name:
        :return:
        """
        return self.rd.hkeys(name)

    def hvalskeys(self, name):
        """
        獲取name對應的hash中所有的value的值
        :param name:
        :return:
        """
        return self.rd.hvals(name)

    def hexistskeys(self,name,key):
        """
        檢查name對應的hash是否存在當前傳入的key 類似字典的in
        :param name:
        :param key:
        :return:
        """
        return self.rd.hexists(name,key)

    def hdelkeys(self,name,*keys):
        """
        將name值對應的hash中指定key的鍵值對刪除
        :param name:
        :param keys: 'k1' or 'k1','k2'
        :return:
        """
        return self.rd.hdel(name,keys)

    def hincrby(self,name,key,amount=1):
        """
        將key對應的value--整數 自增1或者2,或者別的整數 負數就是自減(自增name對應的hash中的指定key的值,不存在則建立key=amount)
        :param name:
        :param key:
        :param amount:
        :return:
        """
        try:
            if not isinstance(amount,int):
                raise TypeError('amount 只能是整數')
            return self.rd.hincrby(name,key,amount)
        except Exception as e:
            return "Func hincrby Error : %d %s" % (e.args[0], e.args[1])

    def hincrbyfloatkeys(self,name,key,amount=1.0):
        """
        將key對應的value--浮點數 自增1.0或者2.0,或者別的浮點數 負數就是自減 (自增name對應的hash中的指定key的值,不存在則建立key=amount)
        :param name:
        :param key:
        :param amount: 自增數(浮點數)
        :return:
        """
        try:
            if not isinstance(amount,float):
                raise TypeError('amount 只能是浮點數')
            return self.rd.hincrbyfloat(name, key, amount)
        except Exception as e:
            return "Func hincrby Error : %d %s" % (e.args[0], e.args[1])

    def hscankeys(self,name,cursor=0,match=None,count=None):
        """
        增量式迭代獲取,對於資料大的資料非常有用,hscan可以實現分片的獲取資料,並非一次性將資料全部獲取完,從而放置記憶體被撐爆
        :param name:
        :param curosr: 遊標(基於遊標分批取獲取資料)
        :param match: 匹配指定key,預設None 表示所有的key
        :param count: 每次分片最少獲取個數,預設None表示採用Redis的預設分片個數
        :return:
        """
        return self.rd.hscan(name,cursor,match,count)

    def hscaniterkeys(self,name,match=None,count=None):
        """
        利用yield 封裝hscan建立生成器,實現分批器redis中獲取資料
        :param name:
        :param match: 匹配指定key,預設表示所有key
        :param count: 每次分片最少獲取個數,預設None表示採用Redis的預設分片個數
        :return:
        """
        return self.rd.hscan_iter(name,match,count)

    # list 操作

    def lpushkeys(self,key,values):
        """
        增加(類似於list的append,只是這裡是從左邊新增加)--沒有就新建
        在name對應的list中新增元素,每個新的元素都新增到列表的最左邊
        lpush('xx',11,12,13)
        :param key:
        :param values:
        :return:
        """
        return self.rd.lpush(key,values)

    def  rpushkeys(self,key,values):
        """
        增加(類似於list的append,只是這裡是從右邊新增加)--沒有就新建
        在name對應的list中新增元素,每個新的元素都新增到列表的最右邊
        rpush('xx',11,12,13)
        :param key:
        :param values:
        :return:
        """
        return self.rd.rpush(key,values)

    def lpushxkeys(self,key,value):
        """
        在key對應的list中新增一個元素,只有key存在時,值新增到列表的最左邊,key不存在則不能建立,但是不報錯
        :param key:
        :param values:
        :return:
        """
        return self.rd.lpushx(key,value)

    def rpushxkeys(self,key,value):
        """
        在key對應的list中新增一個元素,只有key存在時,值新增到列表的最右邊,key不存在則不能建立,但是不報錯
        :param key:
        :param value:
        :return:
        """
        return self.rd.rpushx(key,value)

    def linsertkeys(self,key,where,refvalue,value):
        """
        在key對應的列表的某一個值前或後插入一個新值

        r.linsert("list2", "before", "11", "00")   # 往列表中左邊第一個出現的元素"11"前插入元素"00"

        :param key:
        :param where: before or after
        :param refvalue: 標杆值,即:在它前後插入資料
        :param value:  要插入的資料
        :return:
        """
        try:
            if str(where).lower() not in ['before','after']:
                raise ValueError('where 值只能是 before 或 after')
            return self.rd.linsert(key,where,refvalue,value)
        except Exception as e:
            return "Func linsertkeys Error: %d %s"%(e.args[0],e.args[1])

    def lsetkeys(self,key,index,value):
        """
        對key對應的list中的某一個索引位置重新賦值
        :param key:
        :param index: 索引值,從0 開始
        :param value:
        :return:
        """
        try:
            if not isinstance(index,int):
                raise TypeError('index 只能是整數')
            return self.rd.lset(key,index,value)
        except Exception as e:
            return "Func lsetkeys: %d %s"%(e.args[0],e.args[1])

    def lremkeys(self,key,num,value):
        """
        在key對應的list中刪除指定的值
        :param key:
        :param value:
        :param num: num=0,刪除列表中所有指定值,num=2,從前到後,刪除2個,num=1,從前到後,刪除左邊第一個,num=-2,從後到前,刪除兩個
        :return:
        """
        return self.rd.lrem(key,num,value)

    def lpopkeys(self,key):
        """
        在key 對應的列表的左側獲取第一個元素並在列表中移除,返回值則是第一個元素
        :param key:
        :return:
        """
        return self.rd.lpop(key)

    def rpopkeys(self,key):
        """
        在key 對應的列表的右側獲取第一個元素並在列表中移除,返回值則是第一個元素
        :param key:
        :return:
        """
        return self.rd.rpop(key)

    def ltrimkeys(self,key,start,end):
        """
        在key對應的list中移除沒有在start - end 索引之間的值
        :param key:
        :param start: 索引的開始位置
        :param end: 索引的結束位置
        :return:
        """
        return self.rd.ltrim(key,start,end)

    def lindexkeys(self,key,index):
        """
        在name對應的list中根據索引獲取列表元素
        :param key:
        :param index:
        :return:
        """
        return self.rd.lindex(key,index)

    def rpoplpushkeys(self,srckey,dstkey):
        """
        將元素從一個表移動到另一個表中(從一個列表取出最右邊的元素,同時將其新增至另一個列表的最左邊)
        :param srckey:
        :param detkey:
        :return:
        """
        return self.rd.rpoplpush(srckey,dstkey)

    def brpoplpushkeys(self,srckey,dstkey,timeout=0):
        """
        從一個列表的右側移除一個元素並將其新增到另一個列表的左側,可以設定超時
        :param srckey:
        :param dstkey:
        :param timeout: 當seckey對應的list中沒有資料時,阻塞等待其有資料的超時時間 單位為秒,0表示永遠阻塞
        :return:
        """
        return self.rd.brpoplpush(srckey,dstkey,timeout)

    def blpopkeys(self,keys,timeout):
        """
        將多個列表排序,按照從左到右去pop對應的list元素
        :param keys:
        :param timeout: 超時時間,當元素所有列表的元素獲取完之後,阻塞等待列表內有資料的時間(秒), 0 表示永遠阻塞
        :return:
        """
        return self.rd.blpop(keys,timeout)

    def brpopkeys(self,keys,timeout):
        """
        將多個列表排序,按照從右到左去pop對應的list元素
        :param keys:
        :param timeout: 超時時間,當元素所有列表的元素獲取完之後,阻塞等待列表內有資料的時間(秒), 0 表示永遠阻塞
        :return:
        """
        return self.rd.brpop(keys,timeout)

    def llenkeys(self,key):
        """
        返回key的資料長度
        :param key:
        :return:
        """
        return self.rd.llen(key)

    def lrangekeys(self,key,start=0,end=-1):
        """
        獲取key的全部資料值 通常與llen聯用
        :param key:
        :param start: 起始位置(包括)
        :param end: 結束位置(包括)
        :return:
        """
        return self.rd.lrange(key,start,end)

    def listiterkeys(self,key):
        """
        list增量迭代
        :param key:
        :return: 返回yield 生成器
        """
        list_count = self.rd.llen(key)
        for index in range(list_count):
            yield self.rd.lindex(key,index)

    # set 操作

    def saddkeys(self,key,values):
        """
        :key對應的集合中新增元素,重複的元素將忽略
        saddkeys('xxx',1,2,3,4,5)
        :param key:
        :param values:
        :return:
        """
        return self.rd.sadd(key,values)

    def scardkeys(self,key):
        """
        獲取元素個數,類似於len
        :param key:
        :return:
        """
        return self.rd.scard(key)

    def smemnerkeys(self,key):
        """
        獲取key對應的集合的所有成員
        :param key:
        :return:
        """
        return self.rd.smembers(key)

    def sscankeys(self, key, cursor=0, match=None, count=None):
        """
        獲取集合中所有的成員 -- 元組形式
        :param key:
        :param cursor:
        :param match:
        :param count:
        :return:
        """
        return self.rd.sscan(key,cursor,match,count)

    def sscaniterkeys(self,key,match=0,count=None):
        """
        獲取集合中所有的成員 --迭代器方式
        :param key:
        :param match:
        :param count:
        :return:
        """
        return self.rd.sscan_iter(key,match,count)

    def sdiffkeys(self,keys,*args):
        """
        在第一個key對應的集合中且不在其他key對應的集合的元素集合
        sdiffkeys('a','b) 在集合a中並且不再集合b中
        :param keys:
        :param args:
        :return:
        """
        return self.rd.sdiff(keys,args)

    def sdiffstorekeys(self,dstkey,keys,*args):
        """
        獲取第一個key對應的集合中且不在其他name對應的結合,在將其加入到dstkey對應的集合中
        :param dstkey:
        :param keys:
        :param args:
        :return:
        """
        res = self.rd.sdiffstore(dstkey,keys,args)
        return res

    def sinterkeys(self,keys,*args):
        """
        獲取多個keys對應集合的交集
        :param keys:
        :param args:
        :return:
        """
        return self.rd.sinter(keys,args)

    def sinterstorekeys(self,dstkey,keys,*args):
        """
        獲取多個keys對應集合的交集,再將其加入到dstkey對應的集合中
        :param dstkey:
        :param keys:
        :param args:
        :return:
        """
        res = self.rd.sinterstore(dstkey,keys,args)
        return res

    def sunionkeys(self,keys,*args):
        """
        獲取多個key對應的集合的並集
        :param keys:
        :param args:
        :return:
        """
        return self.rd.sunion(keys,args)

    def sunionstorekeys(self,dstkey,keys,*args):
        """
        獲取多個key對應集合的並集,並將其結果儲存到dstkey對應的集合中
        :param dstkey:
        :param keys:
        :param args:
        :return:
        """
        return self.rd.sunionstore(dstkey,keys,args)

    def sismemberkeys(self,key,value):
        """
        檢查value是否是key對應的結合的成員,結果返回True or False
        :param key:
        :param value:
        :return: True or False
        """
        return self.rd.sismember(key,value)

    def smovekeys(self,srckey,dstkey,value):
        """
        將某個成員從一個集合中移動到另一個集合
        :param srckey:
        :param dstkey:
        :param value:
        :return:
        """
        return self.rd.smove(srckey,dstkey,value)

    def spopkeys(self,key):
        """
        從集合移除一個成員,並將其返回,說明一下,集合是無序的,所有都是隨機刪除的
        :param key:
        :return:
        """
        return self.rd.spop(key)

    def sremkeys(self,key,values):
        """
        在key對應的集合中刪除某些值
        sremkeys('xx','a','b')
        :param key:
        :param values:
        :return:
        """
        return self.rd.srem(key,values)

    #  有序集合  zset 操作

    def zaddkeys(self,key,mapping):
        """
        在key對應的有序集合中新增元素
        zaddkeys('xx',{'k1':1,'k2':2})

        :param key:
        :param args:
        :param kwargs:
        :return:
        """
        return self.rd.zadd(key,mapping)

    def zcardkeys(self,key):
        """
        獲取有序集合元素的個數
        :param key:
        :return:
        """
        return self.rd.zcard(key)

    def zrangekeys(self,key,start,stop,desc=False,withscores=False,score_cast_func=float):
        """
        獲取有序集合索引範圍內的元素
        :param key:
        :param start: 索引起始位置
        :param stop: 索引結束位置
        :param desc: 排序規則,預設按照分數從小到大排序
        :param withscores: 是否獲取元素的分數,預設之火去元素的值
        :param score_cast_func: 對分數進行資料轉換的函式
        :return:
        """
        return self.rd.zrange(key,start,stop,desc,withscores,score_cast_func)

    def zrevrangekeys(self,key,start,end,withscores=False,score_cast_func=float):
        """
        從大到小排序
        :param key:
        :param start:
        :param end:
        :param withscores:
        :param score_cast_func:
        :return:
        """
        return self.rd.zrevrange(key,start,end,withscores,score_cast_func)

    def zrangebyscorekeys(self,key,min,max,start=None,num=None,withscores=False,score_cast_func=float):
        """
        按照分數返回獲取key對應的有序集合的元素
        zrangebyscore("zset3", 15, 25)) # # 在分數是15-25之間,取出符合條件的元素
        zrangebyscore("zset3", 12, 22, withscores=True)   # 在分數是12-22之間,取出符合條件的元素(帶分數)

        :param key:
        :param min:
        :param max:
        :param start:
        :param num:
        :param withscores:
        :param score_cast_func:
        :return:
        """
        return self.rd.zrangebyscore(key,min,max,start,num,withscores,score_cast_func)

    def zrevrangebyscorekeys(self,key,max,min,start=None,num=None,withscores=False,score_cast_func=float):
        """
        按照分數範圍獲取有序集合的元素並排序(預設按照從大到小排序)
        :param key:
        :param max:
        :param min:
        :param start:
        :param num:
        :param withscores:
        :param score_cast_func:
        :return:
        """
        return self.rd.zrevrangebyscore(key,max,min,start,num,withscores,score_cast_func)

    def zscankeys(self,key,cursor=0,match=None,count=None,score_cast_func=float):
        """
        獲取所有元素 -- 預設按照分數順序排序
        :param key:
        :param cursor:
        :param match:
        :param count:
        :param score_cast_func:
        :return:
        """
        return self.rd.zscan(key,cursor,match,count,score_cast_func)

    def zscaniterkeys(self,key,match=None,count=None,score_cast_func=float):
        """
        獲取所有元素的迭代器
        :param key:
        :param match:
        :param count:
        :param score_cast_func:
        :return:
        """
        return self.rd.zscan_iter(key,match,count,score_cast_func)

    def zcountkeys(self,key,min,max):
        """
        獲取key對應的有序集合中分數在[min,max] 之間的個數
        :param key:
        :param min:
        :param max:
        :return:
        """
        return self.rd.zcount(key,min,max)

    def zincrbykey(self,key,value,amount=1):
        """
        自增key對應的有序集合key對應的分數
        :param key:
        :param value:
        :param amount:
        :return:
        """
        return self.rd.zincrby(key,amount,value)

    def zrankeys(self,key,value):
        """
        獲取某個值在key對應的有序集合中的索引(從0開始),預設是從小到大順序
        :param key:
        :param value:
        :return:
        """
        return self.rd.zrank(key,value)

    def zrevrankey(self,key,value):
        """
        獲取某個值在key對應的有序集合中的索引,預設是從大到小順序
        :param key:
        :param value:
        :return:
        """
        return self.rd.zrevrank(key,value)

    def zremkeys(self,key,values):
        """
        刪除key對應的有序集合中值是value的成員
        :param key:
        :param value:
        :return:
        """
        return self.rd.zrem(key,values)

    def zremrangebyrankeys(self,key,min,max):
        """
        刪除根據排行範圍刪除,按照索引刪除
        :param key:
        :param min:
        :param max:
        :return:
        """
        return self.rd.zremrangebyrank(key,min,max)

    def zremrangebyscoreskeys(self,key,min,max):
        """
        刪除根據分數範圍刪除,按照分數範圍刪除
        :param key:
        :param min:
        :param max:
        :return:
        """
        return self.rd.zremrangebyscore(key,min,max)

    def zscoreskeys(self,key,value):
        """
        獲取key對應有序集合中value對應的分數
        :param key:
        :param value:
        :return:
        """
        return self.rd.zscore(key,value)

    # 其他常用操作

    def deletekeys(self,*keys):
        """
        根據刪除redis中的任意資料型別
        deletekeys('gender','cname') 可以刪除多個key
        :param keys:
        :return:
        """
        return self.rd.delete(*keys)

    def existskeys(self,key):
        """
        檢測redis的key 是否存在,存在就返回True,False則不存在
        :param key:
        :return:
        """
        return  self.rd.exists(key)

    def getkeys(self,pattern=""):
        """
        根據模型獲取redis的key

        getkeys * 匹配資料庫中所有 key 。
        getkeys h?llo 匹配 hello , hallo 和 hxllo 等。
        getkeys hllo 匹配 hllo 和 heeeeello 等。
        getkeys h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo

        :param pattern:
        :return:
        """
        return self.rd.keys(pattern)

    def expirekeys(self,key,time):
        """
        設定超時時間,為某個key設定超時時間
        :param key:
        :param time: 秒
        :return:
        """
        return self.rd.expire(key,time)

    def renamekeys(self,srckey,dstkey):
        """
        對key進行重新命名
        :param srckey:
        :param dstkey:
        :return:
        """
        return self.rd.rename(srckey,dstkey)

    def randomkeys(self):
        """
        隨即獲取一個key(不刪除)
        :return:
        """
        return self.rd.randomkey()

    def getkeytypes(self,key):
        """
        獲取key的型別
        :param key:
        :return:
        """
        return self.rd.type(key)

    def scankeys(self,cursor=0,match=None,count=None):
        """
        檢視所有key,終極大招
        :param cursor:
        :param match:
        :param count:
        :return:
        """
        return self.rd.scan(cursor,match,count)

    def scaniterkeys(self,match=None,count=None):
        """
        檢視所有key的迭代器,防止記憶體被撐爆
        :param match:
        :param count:
        :return:
        """
        return self.rd.scan_iter(match,count)

    def dbsizekeys(self):
        """
        當前redis包含多少條資料
        :return:
        """
        return self.rd.dbsize()

    def savekeys(self):
        """
        將資料刷入磁碟中,儲存時阻塞
        :return:
        """
        return self.rd.save()

    def flushdbkeys(self,asynchronous=False):
        """
        清空當前資料庫的所有資料,請謹慎使用
        :param asynchronous:非同步
        :return:
        """
        return self.rd.flushdb(asynchronous)

    def flushallkeys(self,asynchronous=False):
        """
        清空redis所有庫中的資料,不到最後時刻 請不要使用
        :param asynchronous: 非同步
        :return:
        """

        return self.rd.flushall(asynchronous)

    # 建立管道

    """
    redis預設在執行每次請求都會建立(連線池申請連線)和斷開(歸還連線池)一次連線操作,
    如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,
    並且預設情況下一次pipline 是原子性操作。
    管道(pipeline)是redis在提供單個請求中緩衝多條伺服器命令的基類的子類。
    它通過減少伺服器-客戶端之間反覆的TCP資料庫包,從而大大提高了執行批量命令的功能。

    """
    def createpipe(self):
        """
        pipeline(transaction=False)    # 預設的情況下,管道里執行的命令可以保證執行的原子性,執行pipe = r.pipeline(transaction=False)可以禁用這一特性。
        pipe = r.pipeline() # 建立一個管道

        pipe.set('name', 'jack')
        pipe.set('role', 'sb')
        pipe.sadd('faz', 'baz')
        pipe.incr('num')    # 如果num不存在則vaule為1,如果存在,則value自增1
        pipe.execute()

        pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()

        :return:
        """
        return  self.rd.pipeline()

    def disconectkeys(self):
        return self.connPoor.disconnect()

class QueryAllData():
    def __init__(self):
        self.show_tables = config.mysql_show_tables
        self.desc_table = config.mysql_desc_table
        self.query_info = config.mysql_query_info

    def query_tables_info(self):
        mhelper = MySQLHelper()
        tables_list = mhelper.queryTableNums(self.show_tables)
        tables_attr = {}
        for table in tables_list:
            rows = mhelper.queryAll(self.query_info %table)
            tables_attr[table] = rows

        mhelper.close()
        return tables_attr

    def mysql2redis(self,redisobj):

        mysql_data = self.query_tables_info()

        for keys, values in mysql_data.items():
            # keys 為表名字
            for val in values:
                # val 為每一行的資料
                keysorted = sorted(val.keys())
                for s in keysorted:
                    #s 為資料的key
                    item = '%s:%s'%(keys,str(val['id']))
                    ischange = redisobj.hgetkey(item,s)
                    if ischange != val[s]:
                        redisobj.hsetkey(item,s,val[s])

if __name__ == "__main__":

    queryalldata = QueryAllData()
    rhelper = RedisHelper()
    while True:
        queryalldata.mysql2redis(rhelper)

redis 庫用法借鑑 君惜 的內容