tornado redis mysql_tornado-redis入门

#!/usr/bin/env python#encoding: utf-8

importasyncioimportdatetimeimportcollectionsimporttime as mod_timefrom asyncio importFuturefrom collections importnamedtuple, dequefrom tornado.tcpclient importTCPClientfrom tornado.escape importto_unicode, to_basestringclassRedisError(Exception):pass

classConnectionError(RedisError):pass

classRequestError(RedisError):def __init__(self, message, cmd_line=None):

self.message=message

self.cmd_line=cmd_linedef __repr__(self):ifself.cmd_line:return 'RequestError (on %s [%s, %s]): %s'\%(self.cmd_line.cmd, self.cmd_line.args,

self.cmd_line.kwargs, self.message)return 'RequestError: %s' %self.message__str__ = __repr__Message= namedtuple('Message', ('kind', 'channel', 'body', 'pattern'))

GeoData= namedtuple('GeoData', ('member', 'dist', 'coords', 'hash'))defstring_keys_to_dict(key_string, callback):return dict([(key, callback) for key inkey_string.split()])def dict_merge(*dicts):

merged={}for d indicts:

merged.update(d)returnmergeddef reply_to_bool(r, *args, **kwargs):returnbool(r)defmake_reply_assert_msg(msg):def reply_assert_msg(r, *args, **kwargs):return r ==msgreturnreply_assert_msgdef reply_set(r, *args, **kwargs):returnset(r)def reply_dict_from_pairs(r, *args, **kwargs):return dict(zip(r[::2], r[1::2]))def reply_str(r, *args, **kwargs):return r or ''

def reply_int(r, *args, **kwargs):return int(r) if r is not None elseNonedef reply_number(r, *args, **kwargs):if r is notNone:

num=float(r)if notnum.is_integer():returnnumelse:returnint(num)returnNonedef reply_datetime(r, *args, **kwargs):returndatetime.datetime.fromtimestamp(int(r))def reply_pubsub_message(r, *args, **kwargs):"""Handles a Pub/Sub message and packs its data into a Message object."""

if len(r) == 3:

(kind, channel, body)=r

pattern=channelelif len(r) == 4:

(kind, pattern, channel, body)=relif len(r) == 2:

(kind, channel)=r

body= pattern =Noneelse:raise ValueError('Invalid number of arguments')returnMessage(kind, channel, body, pattern)def reply_zset(r, *args, **kwargs):if r and 'WITHSCORES' inargs:return reply_zset_withscores(r, *args, **kwargs)else:returnrdef reply_zset_withscores(r, *args, **kwargs):return list(zip(r[::2], list(map(reply_number, r[1::2]))))def reply_hmget(r, key, *fields, **kwargs):returndict(list(zip(fields, r)))def reply_info(response, *args):

info={}defget_value(value):#Does this string contain subvalues?

if (',' not in value) or ('=' not invalue):returnvalue

sub_dict={}for item in value.split(','):

k, v= item.split('=')try:

sub_dict[k]=int(v)exceptValueError:

sub_dict[k]=vreturnsub_dictfor line inresponse.splitlines():

line=line.strip()if line and not line.startswith('#'):

key, value= line.split(':')try:

info[key]=int(value)exceptValueError:

info[key]=get_value(value)returninfodef reply_ttl(r, *args, **kwargs):return r != -1 and r orNonedef reply_map(*funcs):def reply_fn(r, *args, **kwargs):if len(funcs) !=len(r):raise ValueError('more results than functions to map')return [f(part) for f, part inzip(funcs, r)]returnreply_fndef reply_coords(r, *args, **kwargs):return [(float(c[0]), float(c[1])) for c inr]def reply_geo_radius(r, *args, **kwargs):

geo_data=[]for member inr:

name=member[0]

dist= coords = hs =Noneif 'WITHDIST' inargs:

dist= float(member[1])if 'WITHHASH' in args and 'WITHDIST' inargs:

hs= int(member[2])elif 'WITHHASH' inargs:

hs= int(member[1])if 'WITHCOORD' in args and 'WITHHASH' in args and 'WITHDIST' inargs:

coords= (float(member[3][0]), float(member[3][1]))elif 'WITHCOORD' in args and ('WITHHASH' in args or 'WITHDIST' inargs):

coords= (float(member[2][0]), float(member[2][1]))elif 'WITHCOORD' inargs:

coords= (float(member[1][0]), float(member[1][1]))

geo_data.append(GeoData(name, dist, coords, hs))returngeo_datadefto_list(source):ifisinstance(source, str):return[source]else:returnlist(source)

PUB_SUB_COMMANDS=('SUBSCRIBE','PSUBSCRIBE','UNSUBSCRIBE','PUNSUBSCRIBE',#Not a command at all

'LISTEN',

)

REPLY_MAP=dict_merge(

string_keys_to_dict('AUTH BGREWRITEAOF BGSAVE DEL EXISTS'

'EXPIRE HDEL HEXISTS'

'HMSET MOVE PERSIST RENAMENX SISMEMBER SMOVE'

'SETEX SAVE SETNX MSET',

reply_to_bool),

string_keys_to_dict('BITCOUNT DECRBY GETBIT HLEN INCRBY LINSERT'

'LPUSHX RPUSHX SADD SCARD SDIFFSTORE SETBIT SETRANGE'

'SINTERSTORE STRLEN SUNIONSTORE SETRANGE',

reply_int),

string_keys_to_dict('FLUSHALL FLUSHDB SELECT SET SETEX'

'SHUTDOWN RENAME RENAMENX WATCH UNWATCH',

make_reply_assert_msg('OK')),

string_keys_to_dict('SMEMBERS SINTER SUNION SDIFF', reply_set),

string_keys_to_dict('HGETALL BRPOP BLPOP', reply_dict_from_pairs),

string_keys_to_dict('HGET', reply_str),

string_keys_to_dict('SUBSCRIBE UNSUBSCRIBE LISTEN'

'PSUBSCRIBE UNSUBSCRIBE',

reply_pubsub_message),

string_keys_to_dict('ZRANK ZREVRANK', reply_int),

string_keys_to_dict('ZCOUNT ZCARD', reply_int),

string_keys_to_dict('ZRANGE ZRANGEBYSCORE ZREVRANGE'

'ZREVRANGEBYSCORE',

reply_zset),

string_keys_to_dict('ZSCORE ZINCRBY', reply_number),

string_keys_to_dict('SCAN HSCAN SSCAN', reply_map(reply_int, reply_set)),

string_keys_to_dict('GEODIST', reply_number),

string_keys_to_dict('GEOPOS', reply_coords),

string_keys_to_dict('GEORADIUS GEORADIUSBYMEMBER', reply_geo_radius),

{'HMGET': reply_hmget,'PING': make_reply_assert_msg('PONG'),'LASTSAVE': reply_datetime,'TTL': reply_ttl,'INFO': reply_info,'MULTI_PART': make_reply_assert_msg('QUEUED'),'TIME': lambda x: (int(x[0]), int(x[1])),'ZSCAN': reply_map(reply_int, reply_zset_withscores)}

)classResponseError(RedisError):def __init__(self, message, cmd_line=None):

self.message=message

self.cmd_line=cmd_linedef __repr__(self):ifself.cmd_line:return 'ResponseError (on %s [%s, %s]): %s'\%(self.cmd_line.cmd, self.cmd_line.args,

self.cmd_line.kwargs, self.message)return 'ResponseError: %s' %self.message__str__ = __repr__

classInvalidResponse(RedisError):pass

classLockError(RedisError):"Errors thrown from the Lock"

pass

classCmdLine(object):def __init__(self, cmd, *args, **kwargs):

self.cmd=cmd

self.args=args

self.kwargs=kwargsdef __repr__(self):return self.cmd + '(' + str(self.args) + ',' + str(self.kwargs) + ')'

classTornadoRedis:def __init__(

self,

host='localhost',

port=6379,

password=None,

selected_db=None,

max_connections=None

):

self.host=host

self.port=port

self.password=password

self.selected_db=selected_db#连接池

self.max_connections = max_connections or 2048self._created_connections= 0 #已创建的连接数

self._available_connections = set() #可以使用的连接

self._used_connections = set() #正在使用中的连接

self._waiting_connections = set() #等待使用的连接

def __del__(self):"""Python 垃圾回收机制

Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,

Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该

对象引用计数为 2,依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,

表明程序不再需要该对象,因此 Python 就会回收该对象。"""

for conn inself._available_connections.union(self._used_connections):

conn.disconnect()for conn inself._waiting_connections:

conn.cancel()#Cancel the future and schedule callbacks.

asyncdefget_connection(self):"""Returns a pooled Redis server connection"""

try:

connection=self._available_connections.pop()exceptKeyError:

connection=self.make_connection()ifisinstance(connection, Future):

connection=await connectionifconnection:

await connection.connect()

self._used_connections.add(connection)returnconnectiondefmake_connection(self):"""Creates a new connection to Redis server"""

if self._created_connections >=self.max_connections:

f=Future()

self._waiting_connections.add(f)returnf

self._created_connections+= 1

return Connection(self.host, self.port, selected_db=self.selected_db, password=self.password)defrelease(self, connection):"""Releases the connection back to the pool"""

ifself._waiting_connections:

waiting=self._waiting_connections.pop()

waiting.set_result(connection)else:try:

self._used_connections.remove(connection)except(KeyError, ValueError):passself._available_connections.add(connection)classConnection(object):def __init__(

self,

host='localhost',

port=6379,

selected_db=None,

password=None,

):

self.host=host

self.port=port

self.subscribed=set()

self.subscribe_callbacks=deque()

self.unsubscribe_callbacks=[]

self.password=password

self.selected_db= selected_db or0

self._stream=None

self.client=TCPClient()

self.stream=None

self.info= {'db': 0, 'pass': None}def __del__(self):

self.disconnect()

asyncdefconnect(self):if notself.stream:

self.stream= await self.client.connect(host=self.host, port=self.port)

asyncdef _consume_bulk(self, tail, callback=None):

response= await self.stream.read_until(b'\r\n')#response = await self.stream.read_bytes(int(tail) + 2,partial=True)

ifisinstance(response, Exception):raiseresponseif notresponse:raise ResponseError('EmptyResponse')else:

response=to_unicode(response)

response= response[:-2]returnresponse

asyncdefconsume_multibulk(self, length, cmd_line):

tokens=[]while len(tokens)

data= await self.stream.read_until(b'\r\n')if notdata:raise ResponseError('Not enough data in response to %s, accumulated tokens: %s' %(cmd_line, tokens), cmd_line)

token=await self.process_data(data, cmd_line)

tokens.append(token)returntokens

asyncdefprocess_data(self, data, cmd_line):

data=to_basestring(data)

data= data[:-2] #strip \r\n

if data == '$-1':

response=Noneelif data == '*0' or data == '*-1':

response=[]else:

head, tail= data[0], data[1:]if head == '*':

response=await self.consume_multibulk(int(tail), cmd_line)elif head == '$':

response=await self._consume_bulk(tail)elif head == '+':

response=tailelif head == ':':

response=int(tail)elif head == '-':if tail.startswith('ERR'):

tail= tail[4:]

response=ResponseError(tail, cmd_line)else:raise ResponseError('Unknown response type %s' %head, cmd_line)returnresponse

asyncdef listen(self, callback=None, exit_callback=None):

cmd_listen= CmdLine('LISTEN')whileself.subscribed:try:

data= await self.stream.read_until(b'\r\n')exceptException as e:#Maybe wrong!

importlogging

logging.exception(e)

data=Noneif data isNone:#If disconnected from the redis server clear the list

#of subscriber this client has subscribed to

channels =self.subscribed

self.subscribed=set()#send a message to caller:

#Message(kind='disconnect', channel=set(channel1, ...))

callback(reply_pubsub_message(('disconnect', channels)))returnresponse=await self.process_data(data, cmd_listen)ifisinstance(response, Exception):raiseresponse

result=self.format_reply(cmd_listen, response)if result and result.kind in ('subscribe', 'psubscribe'):

self.on_subscribed(result)if result and result.kind in ('unsubscribe', 'punsubscribe'):

self.on_unsubscribed([result.channel])

callback(result)defformat_reply(self, cmd_line, data):if cmd_line.cmd not inREPLY_MAP:returndatatry:

res= REPLY_MAP[cmd_line.cmd](data, *cmd_line.args, **cmd_line.kwargs)exceptException as e:raiseResponseError('failed to format reply to %s, raw data: %s; err message: %s'

%(cmd_line, data, e), cmd_line

)returnresdefencode(self, value):if notisinstance(value, str):

value=str(value)

value= value.encode('utf-8')returnvaluedef format_command(self, *tokens, **kwargs):

cmds=[]for t intokens:

e_t=self.encode(t)

e_t_s=to_basestring(e_t)

cmds.append('$%s\r\n%s\r\n' %(len(e_t), e_t_s))

data= '*%s\r\n%s' % (len(tokens), ''.join(cmds))return bytes(data, encoding='utf-8')

asyncdef execute_command(self, cmd, *args, **kwargs):

result=None

cmd_line= CmdLine(cmd, *args, **kwargs)

n_tries= 2

while n_tries >0:

n_tries-= 1

if not self.subscribed and cmd not in ('AUTH', 'SELECT'):if self.password and self.info.get('pass', None) !=self.password:

await self.auth(self.password)if self.selected_db and self.info.get('db', 0) !=self.selected_db:

await self.select(self.selected_db)

command= self.format_command(cmd, *args, **kwargs)

await self.stream.write(command)

listening= ((cmd in PUB_SUB_COMMANDS) or (self.subscribed and cmd == 'PUBLISH'))iflistening:breakdata= await self.stream.read_until(b'\r\n')

resp=await self.process_data(data, cmd_line)

result=self.format_reply(cmd_line, resp)returnresult### MAINTENANCE

def bgrewriteaof(self, callback=None):

self.execute_command('BGREWRITEAOF', callback=callback)def dbsize(self, callback=None):

self.execute_command('DBSIZE', callback=callback)def flushall(self, callback=None):

self.execute_command('FLUSHALL', callback=callback)def flushdb(self, callback=None):

self.execute_command('FLUSHDB', callback=callback)def ping(self, callback=None):

self.execute_command('PING', callback=callback)def object(self, infotype, key, callback=None):

self.execute_command('OBJECT', infotype, key, callback=callback)def info(self, section_name=None, callback=None):

args= ('INFO',)ifsection_name:

args+=(section_name,)

self.execute_command(*args, callback=callback)def echo(self, value, callback=None):

self.execute_command('ECHO', value, callback=callback)def time(self, callback=None):"""Returns the server time as a 2-item tuple of ints:

(seconds since epoch, microseconds into this second)."""self.execute_command('TIME', callback=callback)def select(self, db, callback=None):

self.selected_db=db#if self.connection.info.get('db', None) != db:

#self.connection.info['db'] = db

#self.execute_command('SELECT', '%s' % db, callback=callback)

#elif callback:

#callback(True)

def shutdown(self, callback=None):

self.execute_command('SHUTDOWN', callback=callback)def save(self, callback=None):

self.execute_command('SAVE', callback=callback)def bgsave(self, callback=None):

self.execute_command('BGSAVE', callback=callback)def lastsave(self, callback=None):

self.execute_command('LASTSAVE', callback=callback)def keys(self, pattern='*', callback=None):

self.execute_command('KEYS', pattern, callback=callback)

asyncdef auth(self, password, callback=None):

self.password=passwordif self.info.get('pass', None) !=password:

self.info['pass'] =password

await self.execute_command('AUTH', password, callback=callback)#elif callback:

#callback(True)

### BASIC KEY COMMANDS

def append(self, key, value, callback=None):

self.execute_command('APPEND', key, value, callback=callback)def getrange(self, key, start, end, callback=None):"""Returns the substring of the string value stored at ``key``,

determined by the offsets ``start`` and ``end`` (both are inclusive)"""self.execute_command('GETRANGE', key, start, end, callback=callback)def expire(self, key, ttl, callback=None):

self.execute_command('EXPIRE', key, ttl, callback=callback)def expireat(self, key, when, callback=None):"""Sets an expire flag on ``key``. ``when`` can be represented

as an integer indicating unix time or a Python datetime.datetime object."""

ifisinstance(when, datetime.datetime):

when=int(mod_time.mktime(when.timetuple()))

self.execute_command('EXPIREAT', key, when, callback=callback)def ttl(self, key, callback=None):

self.execute_command('TTL', key, callback=callback)def type(self, key, callback=None):

self.execute_command('TYPE', key, callback=callback)def randomkey(self, callback=None):

self.execute_command('RANDOMKEY', callback=callback)def rename(self, src, dst, callback=None):

self.execute_command('RENAME', src, dst, callback=callback)def renamenx(self, src, dst, callback=None):

self.execute_command('RENAMENX', src, dst, callback=callback)def move(self, key, db, callback=None):

self.execute_command('MOVE', key, db, callback=callback)def persist(self, key, callback=None):

self.execute_command('PERSIST', key, callback=callback)def pexpire(self, key, time, callback=None):"""Set an expire flag on key ``key`` for ``time`` milliseconds.

``time`` can be represented by an integer or a Python timedelta

object."""

ifisinstance(time, datetime.timedelta):

ms= int(time.microseconds / 1000)

time= time.seconds + time.days * 24 * 3600 * 1000 +ms

self.execute_command('PEXPIRE', key, time, callback=callback)def pexpireat(self, key, when, callback=None):"""Set an expire flag on key ``key``. ``when`` can be represented

as an integer representing unix time in milliseconds (unix time * 1000)

or a Python datetime.datetime object."""

ifisinstance(when, datetime.datetime):

ms= int(when.microsecond / 1000)

when= int(mod_time.mktime(when.timetuple())) * 1000 +ms

self.execute_command('PEXPIREAT', key, when, callback=callback)def pttl(self, key, callback=None):"Returns the number of milliseconds until the key will expire"self.execute_command('PTTL', key, callback=callback)def substr(self, key, start, end, callback=None):

self.execute_command('SUBSTR', key, start, end, callback=callback)def delete(self, *keys, **kwargs):

self.execute_command('DEL', *keys, callback=kwargs.get('callback'))

asyncdef set(self, key, value, expire=None, pexpire=None,

only_if_not_exists=False, only_if_exists=False, callback=None):

args=[]if expire is notNone:

args.extend(("EX", expire))if pexpire is notNone:

args.extend(("PX", pexpire))if only_if_not_exists andonly_if_exists:raise ValueError("only_if_not_exists and only_if_exists"

"cannot be true simultaneously")ifonly_if_not_exists:

args.append("NX")ifonly_if_exists:

args.append("XX")

await self.execute_command('SET', key, value, *args, callback=callback)def setex(self, key, ttl, value, callback=None):

self.execute_command('SETEX', key, ttl, value, callback=callback)def setnx(self, key, value, callback=None):

self.execute_command('SETNX', key, value, callback=callback)def setrange(self, key, offset, value, callback=None):

self.execute_command('SETRANGE', key, offset, value, callback=callback)def strlen(self, key, callback=None):

self.execute_command('STRLEN', key, callback=callback)def mset(self, mapping, callback=None):

items= [i for k, v in mapping.items() for i in(k, v)]

self.execute_command('MSET', *items, callback=callback)def msetnx(self, mapping, callback=None):

items= [i for k, v in mapping.items() for i in(k, v)]

self.execute_command('MSETNX', *items, callback=callback)

asyncdef get(self, key, callback=None):return await self.execute_command('GET', key, callback=callback)def mget(self, keys, callback=None):

self.execute_command('MGET', *keys, callback=callback)def getset(self, key, value, callback=None):

self.execute_command('GETSET', key, value, callback=callback)def exists(self, key, callback=None):

self.execute_command('EXISTS', key, callback=callback)def sort(self, key, start=None, num=None, by=None, get=None, desc=False,

alpha=False, store=None, callback=None):if ((start is not None and num is None) or(numis not None and start isNone)):raise ValueError("``start`` and ``num`` must both be specified")

tokens=[key]if by is notNone:

tokens.append('BY')

tokens.append(by)if start is not None and num is notNone:

tokens.append('LIMIT')

tokens.append(start)

tokens.append(num)if get is notNone:

tokens.append('GET')

tokens.append(get)ifdesc:

tokens.append('DESC')ifalpha:

tokens.append('ALPHA')if store is notNone:

tokens.append('STORE')

tokens.append(store)

self.execute_command('SORT', *tokens, callback=callback)def getbit(self, key, offset, callback=None):

self.execute_command('GETBIT', key, offset, callback=callback)def setbit(self, key, offset, value, callback=None):

self.execute_command('SETBIT', key, offset, value, callback=callback)def bitcount(self, key, start=None, end=None, callback=None):

args= [a for a in (key, start, end) if a is notNone]

kwargs= {'callback': callback}

self.execute_command('BITCOUNT', *args, **kwargs)def bitop(self, operation, dest, *keys, **kwargs):"""Perform a bitwise operation using ``operation`` between ``keys`` and

store the result in ``dest``."""kwargs= {'callback': kwargs.get('callback', None)}

self.execute_command('BITOP', operation, dest, *keys, **kwargs)### COUNTERS COMMANDS

def incr(self, key, callback=None):

self.execute_command('INCR', key, callback=callback)def decr(self, key, callback=None):

self.execute_command('DECR', key, callback=callback)def incrby(self, key, amount, callback=None):

self.execute_command('INCRBY', key, amount, callback=callback)def incrbyfloat(self, key, amount=1.0, callback=None):

self.execute_command('INCRBYFLOAT', key, amount, callback=callback)def decrby(self, key, amount, callback=None):

self.execute_command('DECRBY', key, amount, callback=callback)### LIST COMMANDS

def blpop(self, keys, timeout=0, callback=None):

tokens=to_list(keys)

tokens.append(timeout)

self.execute_command('BLPOP', *tokens, callback=callback)def brpop(self, keys, timeout=0, callback=None):

tokens=to_list(keys)

tokens.append(timeout)

self.execute_command('BRPOP', *tokens, callback=callback)def brpoplpush(self, src, dst, timeout=1, callback=None):

tokens=[src, dst, timeout]

self.execute_command('BRPOPLPUSH', *tokens, callback=callback)def lindex(self, key, index, callback=None):

self.execute_command('LINDEX', key, index, callback=callback)def llen(self, key, callback=None):

self.execute_command('LLEN', key, callback=callback)def lrange(self, key, start, end, callback=None):

self.execute_command('LRANGE', key, start, end, callback=callback)def lrem(self, key, value, num=0, callback=None):

self.execute_command('LREM', key, num, value, callback=callback)def lset(self, key, index, value, callback=None):

self.execute_command('LSET', key, index, value, callback=callback)def ltrim(self, key, start, end, callback=None):

self.execute_command('LTRIM', key, start, end, callback=callback)def lpush(self, key, *values, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('LPUSH', key, *values, callback=callback)def lpushx(self, key, value, callback=None):

self.execute_command('LPUSHX', key, value, callback=callback)def linsert(self, key, where, refvalue, value, callback=None):

self.execute_command('LINSERT', key, where, refvalue, value,

callback=callback)def rpush(self, key, *values, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('RPUSH', key, *values, callback=callback)def rpushx(self, key, value, **kwargs):"Push ``value`` onto the tail of the list ``name`` if ``name`` exists"callback= kwargs.get('callback', None)

self.execute_command('RPUSHX', key, value, callback=callback)def lpop(self, key, callback=None):

self.execute_command('LPOP', key, callback=callback)def rpop(self, key, callback=None):

self.execute_command('RPOP', key, callback=callback)def rpoplpush(self, src, dst, callback=None):

self.execute_command('RPOPLPUSH', src, dst, callback=callback)### SET COMMANDS

def sadd(self, key, *values, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('SADD', key, *values, callback=callback)def srem(self, key, *values, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('SREM', key, *values, callback=callback)def scard(self, key, callback=None):

self.execute_command('SCARD', key, callback=callback)def spop(self, key, callback=None):

self.execute_command('SPOP', key, callback=callback)def smove(self, src, dst, value, callback=None):

self.execute_command('SMOVE', src, dst, value, callback=callback)def sismember(self, key, value, callback=None):

self.execute_command('SISMEMBER', key, value, callback=callback)def smembers(self, key, callback=None):

self.execute_command('SMEMBERS', key, callback=callback)def srandmember(self, key, number=None, callback=None):ifnumber:

self.execute_command('SRANDMEMBER', key, number, callback=callback)else:

self.execute_command('SRANDMEMBER', key, callback=callback)def sinter(self, keys, callback=None):

self.execute_command('SINTER', *keys, callback=callback)def sdiff(self, keys, callback=None):

self.execute_command('SDIFF', *keys, callback=callback)def sunion(self, keys, callback=None):

self.execute_command('SUNION', *keys, callback=callback)def sinterstore(self, keys, dst, callback=None):

self.execute_command('SINTERSTORE', dst, *keys, callback=callback)def sunionstore(self, keys, dst, callback=None):

self.execute_command('SUNIONSTORE', dst, *keys, callback=callback)def sdiffstore(self, keys, dst, callback=None):

self.execute_command('SDIFFSTORE', dst, *keys, callback=callback)### SORTED SET COMMANDS

def zadd(self, key, *score_value, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('ZADD', key, *score_value, callback=callback)def zcard(self, key, callback=None):

self.execute_command('ZCARD', key, callback=callback)def zincrby(self, key, value, amount, callback=None):

self.execute_command('ZINCRBY', key, amount, value, callback=callback)def zrank(self, key, value, callback=None):

self.execute_command('ZRANK', key, value, callback=callback)def zrevrank(self, key, value, callback=None):

self.execute_command('ZREVRANK', key, value, callback=callback)def zrem(self, key, *values, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('ZREM', key, *values, callback=callback)def zcount(self, key, start, end, callback=None):

self.execute_command('ZCOUNT', key, start, end, callback=callback)def zscore(self, key, value, callback=None):

self.execute_command('ZSCORE', key, value, callback=callback)def zrange(self, key, start, num, with_scores=True, callback=None):

tokens=[key, start, num]ifwith_scores:

tokens.append('WITHSCORES')

self.execute_command('ZRANGE', *tokens, callback=callback)def zrevrange(self, key, start, num, with_scores, callback=None):

tokens=[key, start, num]ifwith_scores:

tokens.append('WITHSCORES')

self.execute_command('ZREVRANGE', *tokens, callback=callback)def zrangebyscore(self, key, start, end, offset=None, limit=None,

with_scores=False, callback=None):

tokens=[key, start, end]if offset is notNone:

tokens.append('LIMIT')

tokens.append(offset)

tokens.append(limit)ifwith_scores:

tokens.append('WITHSCORES')

self.execute_command('ZRANGEBYSCORE', *tokens, callback=callback)def zrevrangebyscore(self, key, end, start, offset=None, limit=None,

with_scores=False, callback=None):

tokens=[key, end, start]if offset is notNone:

tokens.append('LIMIT')

tokens.append(offset)

tokens.append(limit)ifwith_scores:

tokens.append('WITHSCORES')

self.execute_command('ZREVRANGEBYSCORE', *tokens, callback=callback)def zremrangebyrank(self, key, start, end, callback=None):

self.execute_command('ZREMRANGEBYRANK', key, start, end,

callback=callback)def zremrangebyscore(self, key, start, end, callback=None):

self.execute_command('ZREMRANGEBYSCORE', key, start, end,

callback=callback)def zinterstore(self, dest, keys, aggregate=None, callback=None):return self._zaggregate('ZINTERSTORE', dest, keys, aggregate, callback)def zunionstore(self, dest, keys, aggregate=None, callback=None):return self._zaggregate('ZUNIONSTORE', dest, keys, aggregate, callback)def_zaggregate(self, command, dest, keys, aggregate, callback):

tokens=[dest, len(keys)]ifisinstance(keys, dict):

items=list(keys.items())

keys= [i[0] for i initems]

weights= [i[1] for i initems]else:

weights=None

tokens.extend(keys)ifweights:

tokens.append('WEIGHTS')

tokens.extend(weights)ifaggregate:

tokens.append('AGGREGATE')

tokens.append(aggregate)

self.execute_command(command,*tokens, callback=callback)### HASH COMMANDS

def hgetall(self, key, callback=None):

self.execute_command('HGETALL', key, callback=callback)def hmset(self, key, mapping, callback=None):

items= [i for k, v in mapping.items() for i in(k, v)]

self.execute_command('HMSET', key, *items, callback=callback)def hset(self, key, field, value, callback=None):

self.execute_command('HSET', key, field, value, callback=callback)def hsetnx(self, key, field, value, callback=None):

self.execute_command('HSETNX', key, field, value, callback=callback)def hget(self, key, field, callback=None):

self.execute_command('HGET', key, field, callback=callback)def hdel(self, key, *fields, **kwargs):

callback= kwargs.get('callback')

self.execute_command('HDEL', key, *fields, callback=callback)def hlen(self, key, callback=None):

self.execute_command('HLEN', key, callback=callback)def hexists(self, key, field, callback=None):

self.execute_command('HEXISTS', key, field, callback=callback)def hincrby(self, key, field, amount=1, callback=None):

self.execute_command('HINCRBY', key, field, amount, callback=callback)def hincrbyfloat(self, key, field, amount=1.0, callback=None):

self.execute_command('HINCRBYFLOAT', key, field, amount,

callback=callback)def hkeys(self, key, callback=None):

self.execute_command('HKEYS', key, callback=callback)def hmget(self, key, fields, callback=None):

self.execute_command('HMGET', key, *fields, callback=callback)def hvals(self, key, callback=None):

self.execute_command('HVALS', key, callback=callback)### SCAN COMMANDS

def scan(self, cursor, count=None, match=None, callback=None):

self._scan('SCAN', cursor, count, match, callback)def hscan(self, key, cursor, count=None, match=None, callback=None):

self._scan('HSCAN', cursor, count, match, callback, key=key)def sscan(self, key, cursor, count=None, match=None, callback=None):

self._scan('SSCAN', cursor, count, match, callback, key=key)def zscan(self, key, cursor, count=None, match=None, callback=None):

self._scan('ZSCAN', cursor, count, match, callback, key=key)def _scan(self, cmd, cursor, count, match, callback, key=None):

tokens=[cmd]

keyandtokens.append(key)

tokens.append(cursor)

matchand tokens.extend(['MATCH', match])

countand tokens.extend(['COUNT', count])

self.execute_command(*tokens, callback=callback)### GEO COMMANDS

def geoadd(self, key, longitude, latitude, member, *args, **kwargs):

self.execute_command('GEOADD', key, longitude, latitude, member, *args, **kwargs)def geodist(self, key, member1, member2, unit='m', callback=None):

self.execute_command('GEODIST', key, member1, member2, unit, callback=callback)def geohash(self, key, member, *args, **kwargs):

self.execute_command('GEOHASH', key, member, *args, **kwargs)def geopos(self, key, member, *args, **kwargs):

self.execute_command('GEOPOS', key, member, *args, **kwargs)def georadius(self, key, longitude, latitude, radius, unit='m',

with_coord=False, with_dist=False, with_hash=False,

count=None, sort=None, callback=None):

args=[]ifwith_coord:

args.append('WITHCOORD')ifwith_dist:

args.append('WITHDIST')ifwith_hash:

args.append('WITHHASH')if count and count >0:

args.append(count)if sort and sort in ['ASC', 'DESC']:

args.append(sort)

self.execute_command('GEORADIUS', key, longitude, latitude, radius, unit, callback=callback, *args)def georadiusbymember(self, key, member, radius, unit='m',

with_coord=False, with_dist=False, with_hash=False,

count=None, sort=None, callback=None):

args=[]ifwith_coord:

args.append('WITHCOORD')ifwith_dist:

args.append('WITHDIST')ifwith_hash:

args.append('WITHHASH')if count and count >0:

args.append(count)if sort and sort in ['ASC', 'DESC']:

args.append(sort)

self.execute_command('GEORADIUSBYMEMBER', key, member, radius, unit, callback=callback, *args)### PUBSUB

asyncdef subscribe(self, channels, callback=None):

await self._subscribe('SUBSCRIBE', channels, callback=callback)

asyncdef psubscribe(self, channels, callback=None):

await self._subscribe('PSUBSCRIBE', channels, callback=callback)

asyncdef _subscribe(self, cmd, channels, callback=None):ifisinstance(channels, str):

channels=[channels]if notself.subscribed:

self.on_subscribed(Message(kind='subscribe',

channel=channels[0],

body=None,

pattern=None)

)for channel inchannels:

self.subscribe_callbacks.append((channel, None))#Do not execute the same callback multiple times

await self.execute_command(cmd,*channels, callback=callback)defon_subscribed(self, result):

self.subscribed.add(result.channel)def on_unsubscribed(self, channels, *args, **kwargs):

channels=set(channels)

self.subscribed-=channels

asyncdef unsubscribe(self, channels, callback=None):

await self._unsubscribe('UNSUBSCRIBE', channels, callback=callback)

asyncdef punsubscribe(self, channels, callback=None):

await self._unsubscribe('PUNSUBSCRIBE', channels, callback=callback)

asyncdef _unsubscribe(self, cmd, channels, callback=None):ifisinstance(channels, str):

channels=[channels]

await self.execute_command(cmd,*channels)

asyncdef publish(self, channel, message, callback=None):

await self.execute_command('PUBLISH', channel, message, callback=callback)### CAS

def watch(self, *key_names, **kwargs):

callback= kwargs.get('callback', None)

self.execute_command('WATCH', *key_names, callback=callback)def unwatch(self, callback=None):

self.execute_command('UNWATCH', callback=callback)### SCRIPTING COMMANDS

def eval(self, script, keys=None, args=None, callback=None):if keys isNone:

keys=[]if args isNone:

args=[]

num_keys=len(keys)

_args= keys +args

self.execute_command('EVAL', script, num_keys,*_args, callback=callback)def evalsha(self, shahash, keys=None, args=None, callback=None):if keys isNone:

keys=[]if args isNone:

args=[]

num_keys=len(keys)

keys.extend(args)

self.execute_command('EVALSHA', shahash, num_keys,*keys, callback=callback)def script_exists(self, shahashes, callback=None):#not yet implemented in the redis protocol

self.execute_command('SCRIPT EXISTS', *shahashes, callback=callback)def script_flush(self, callback=None):#not yet implemented in the redis protocol

self.execute_command('SCRIPT FLUSH', callback=callback, verbose=True)def script_kill(self, callback=None):#not yet implemented in the redis protocol

self.execute_command('SCRIPT KILL', callback=callback)def script_load(self, script, callback=None):#not yet implemented in the redis protocol

self.execute_command('SCRIPT LOAD', script, callback=callback)defdisconnect(self):

self.stream.close()

self.client.close()

asyncdefmain():#测试get and set

"""host="192.168.1.252",

port=6379,

password="123456""""client= TornadoRedis(host="192.168.1.252", port=6379, password="123456", max_connections=2)

conn1=await client.get_connection()

client.release(conn1)

conn2=await client.get_connection()

conn3=await client.get_connection()

await conn1.set(key="abc", value="data", expire=100)

tmp= await conn1.get("abc")print(tmp)if __name__ == "__main__":

loop=asyncio.get_event_loop()#执行coroutine

loop.run_until_complete(main())

loop.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值