1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
#!/usr/bin/env python
# coding: utf-8
# refer: https://github.com/ideawu/ssdb/blob/master/tools/redis-import.php
# Notice: for zset, float score will be converted to integer.
import sys
import os
from collections import OrderedDict as od
import redis
import ledis
total = 0
entries = 0
def scan_available(redis_client):
""""Scan Command is available since redis-server 2.8.0"""
if "scan" in dir(redis_client):
info = redis_client.info()
server_version = info["redis_version"]
version_list = server_version.split(".")
if len(version_list) > 2:
n = int(version_list[0]) * 10 + int(version_list[1])
if n >= 28:
return True
return False
def set_ttl(redis_client, ledis_client, key, k_type):
k_types = {
"string": ledis_client.expire,
"list": ledis_client.lexpire,
"hash": ledis_client.hexpire,
"set": ledis_client.zexpire,
"zset": ledis_client.zexpire
}
timeout = redis_client.ttl(key)
if timeout > 0:
k_types[k_type](key, timeout)
def copy_key(redis_client, ledis_client, key, convert=False):
global entries
k_type = redis_client.type(key)
if k_type == "string":
value = redis_client.get(key)
ledis_client.set(key, value)
set_ttl(redis_client, ledis_client, key, k_type)
entries += 1
elif k_type == "list":
_list = redis_client.lrange(key, 0, -1)
for value in _list:
ledis_client.rpush(key, value)
set_ttl(redis_client, ledis_client, key, k_type)
entries += 1
elif k_type == "hash":
mapping = od(redis_client.hgetall(key))
ledis_client.hmset(key, mapping)
set_ttl(redis_client, ledis_client, key, k_type)
entries += 1
elif k_type == "zset":
out = redis_client.zrange(key, 0, -1, withscores=True)
pieces = od()
for i in od(out).iteritems():
pieces[i[0]] = int(i[1])
ledis_client.zadd(key, **pieces)
set_ttl(redis_client, ledis_client, key, k_type)
entries += 1
else:
print "KEY %s of TYPE %s is not supported by LedisDB." % (key, k_type)
def copy_keys(redis_client, ledis_client, keys, convert=False):
for key in keys:
copy_key(redis_client, ledis_client, key, convert=convert)
def scan(redis_client, count=1000):
keys = []
total = redis_client.dbsize()
if total > 1000:
print "It may take a while, be patient please."
first = True
cursor = 0
while cursor != 0 or first:
cursor, data = redis_client.scan(cursor, count=count)
keys.extend(data)
first = False
assert len(keys) == total
return keys, total
def copy(redis_client, ledis_client, count=1000, convert=False):
if scan_available(redis_client):
print "\nTransfer begin ...\n"
keys, total = scan(redis_client, count=count)
copy_keys(redis_client, ledis_client, keys, convert=convert)
else:
msg = """We do not support Redis version less than 2.8.0.
Please check both your redis server version and redis-py
version.
"""
print msg
sys.exit()
print "%d keys, %d entries copied" % (total, entries)
def usage():
usage = """
Usage:
python %s redis_host redis_port redis_db ledis_host ledis_port
"""
print usage % os.path.basename(sys.argv[0])
def get_prompt(choice):
yes = set(['yes', 'ye', 'y', ''])
no = set(['no', 'n'])
if choice in yes:
return True
elif choice in no:
return False
else:
sys.stdout.write("Please respond with 'yes' or 'no'")
def main():
if len(sys.argv) < 6:
usage()
sys.exit()
convert = False
if len(sys.argv) >= 6:
(redis_host, redis_port, redis_db, ledis_host, ledis_port) = sys.argv[1:6]
if int(redis_db) >= 16:
print redis_db
sys.exit("LedisDB only support 16 databases([0-15]")
choice = raw_input("[y/N]").lower()
if not get_prompt(choice):
sys.exit("No proceed")
redis_c = redis.Redis(host=redis_host, port=int(redis_port), db=int(redis_db))
ledis_c = ledis.Ledis(host=ledis_host, port=int(ledis_port), db=int(redis_db))
try:
redis_c.ping()
except redis.ConnectionError:
print "Could not connect to Redis Server"
sys.exit()
try:
ledis_c.ping()
except redis.ConnectionError:
print "Could not connect to LedisDB Server"
sys.exit()
copy(redis_c, ledis_c, convert=convert)
print "Done\n"
if __name__ == "__main__":
main()
|