databases.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import bson
  2. import pymongo
  3. import redis
  4. from redis._compat import unicode, long, basestring
  5. from redis.connection import Encoder as RedisEncoder
  6. from redis.exceptions import DataError
  7. # import config.load as settings
  8. import setting as settings
  9. # ---------------------------------- mongo ----------------------------------
  10. MONGO_URI_CLIENTS = {} # a dictionary hold all client with uri as key
  11. def mongo_client(cfg=None, host=None, port=None, fork=False, **kwargs):
  12. if host is not None and port is not None:
  13. uri = f'mongodb://{host}:{port}'
  14. else:
  15. _cfg = (cfg or settings.mongo_conf)
  16. uri = f'mongodb://{_cfg["host"]}:{_cfg["port"]}'
  17. if fork:
  18. return pymongo.MongoClient(uri, **kwargs)
  19. global MONGO_URI_CLIENTS
  20. matched_client = MONGO_URI_CLIENTS.get(uri)
  21. if matched_client is None:
  22. new_client = pymongo.MongoClient(uri, **kwargs)
  23. if new_client is not None:
  24. MONGO_URI_CLIENTS[uri] = new_client
  25. return new_client
  26. return matched_client
  27. def mongo_database(name: str, **kw):
  28. client = mongo_client(**kw)
  29. return client.get_database(name)
  30. def mongo_table(db: str, name: str, **kw):
  31. database = mongo_database(db, **kw)
  32. return database.get_collection(name)
  33. def int2long(param: int):
  34. """int 转换成 long """
  35. return bson.int64.Int64(param)
  36. def object_id(_id: str):
  37. return bson.objectid.ObjectId(_id)
  38. # ---------------------------------- redis ----------------------------------
  39. def redis_client(cfg=None):
  40. class Encoder(RedisEncoder):
  41. def encode(self, value):
  42. "Return a bytestring or bytes-like representation of the value"
  43. if isinstance(value, (bytes, memoryview)):
  44. return value
  45. # elif isinstance(value, bool):
  46. # # special case bool since it is a subclass of int
  47. # raise DataError(
  48. # "Invalid input of type: 'bool'. Convert to a "
  49. # "bytes, string, int or float first."
  50. # )
  51. elif isinstance(value, float):
  52. value = repr(value).encode()
  53. elif isinstance(value, (int, long)):
  54. # python 2 repr() on longs is '123L', so use str() instead
  55. value = str(value).encode()
  56. elif isinstance(value, (list, dict, tuple)):
  57. value = unicode(value)
  58. elif not isinstance(value, basestring):
  59. # a value we don't know how to deal with. throw an error
  60. typename = type(value).__name__
  61. raise DataError(
  62. "Invalid input of type: '%s'. Convert to a "
  63. "bytes, string, int or float first." % typename
  64. )
  65. if isinstance(value, unicode):
  66. value = value.encode(self.encoding, self.encoding_errors)
  67. return value
  68. redis.connection.Encoder = Encoder
  69. if cfg is None:
  70. cfg = settings.redis_conf
  71. return redis.StrictRedis(host=cfg['host'], port=cfg['port'],
  72. password=cfg['pwd'], db=cfg['db'],
  73. decode_responses=True)