github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/server/block/db/base.py (about) 1 #!/usr/bin/python 2 # -*- coding: utf-8 -*- 3 4 from sqlalchemy.ext.declarative import DeclarativeMeta 5 from sqlalchemy.orm import object_mapper 6 import simplejson 7 import six 8 from datetime import datetime 9 import threading 10 from util.ini_client import ini_load 11 from enginefacade import EngineFacade 12 13 _conf = ini_load('config/mysql.ini') 14 _dic_con = _conf.get_fields('product_db') 15 16 connect = 'mysql://{0}:{1}@{2}:{3}/{4}?charset=utf8'.format( 17 _dic_con.get('user'), 18 _dic_con.get('password'), 19 _dic_con.get('host'), 20 _dic_con.get('port', 3306), 21 _dic_con.get('database') 22 ) 23 24 _LOCK = threading.Lock() 25 _FACADE = None 26 27 28 def _create_facade_lazily(): 29 global _LOCK 30 with _LOCK: 31 global _FACADE 32 if _FACADE is None: 33 args = { 34 "encoding": "utf8", 35 "convert_unicode": True, 36 "pool_recycle" : 3600,#该值必须小于数据库服务器的interactive_timeout,连接池中的空闲连接超过1小时候,自动释放。 37 } 38 _FACADE = EngineFacade(connect, **args) 39 40 return _FACADE 41 42 def get_engine(): 43 facade = _create_facade_lazily() 44 return facade.get_engine() 45 46 47 def get_session(): 48 facade = _create_facade_lazily() 49 return facade.get_session() 50 51 52 class ModelBase(six.Iterator): 53 """Base class for models.""" 54 __table_initialized__ = False 55 56 def save(self, session): 57 """Save this object.""" 58 with session.begin(subtransactions=True): 59 session.add(self) 60 session.flush() 61 62 def __setitem__(self, key, value): 63 setattr(self, key, value) 64 65 def __getitem__(self, key): 66 return getattr(self, key) 67 68 def __contains__(self, key): 69 try: 70 getattr(self, key) 71 except AttributeError: 72 return False 73 else: 74 return True 75 76 def get(self, key, default=None): 77 return getattr(self, key, default) 78 79 @property 80 def _extra_keys(self): 81 return [] 82 83 def __iter__(self): 84 columns = list(dict(object_mapper(self).columns).keys()) 85 # NOTE(russellb): Allow models to specify other keys that can be looked 86 # up, beyond the actual db columns. An example would be the 'name' 87 # property for an Instance. 88 columns.extend(self._extra_keys) 89 90 return ModelIterator(self, iter(columns)) 91 92 def update(self, values): 93 """Make the model object behave like a dict.""" 94 for k, v in six.iteritems(values): 95 setattr(self, k, v) 96 97 def _as_dict(self): 98 """Make the model object behave like a dict. 99 100 Includes attributes from joins. 101 """ 102 local = dict((key, value) for key, value in self) 103 joined = dict([(k, v) for k, v in six.iteritems(self.__dict__) 104 if not k[0] == '_']) 105 local.update(joined) 106 return local 107 108 def iteritems(self): 109 """Make the model object behave like a dict.""" 110 return six.iteritems(self._as_dict()) 111 112 def items(self): 113 """Make the model object behave like a dict.""" 114 return self._as_dict().items() 115 116 def keys(self): 117 """Make the model object behave like a dict.""" 118 return [key for key, value in self.iteritems()] 119 120 class ModelIterator(six.Iterator): 121 122 def __init__(self, model, columns): 123 self.model = model 124 self.i = columns 125 126 def __iter__(self): 127 return self 128 129 # In Python 3, __next__() has replaced next(). 130 def __next__(self): 131 n = six.advance_iterator(self.i) 132 return n, getattr(self.model, n) 133 134 class DateJsonEncoder(simplejson.JSONEncoder): 135 def default(self, obj): 136 if isinstance(obj, datetime): 137 return obj.__str__() 138 return simplejson.JSONEncoder.default(self, obj) 139 140 class AlchemyEncoder(simplejson.JSONEncoder): 141 def default(self, obj): 142 if isinstance(obj.__class__, DeclarativeMeta): 143 # an SQLAlchemy class 144 fields = {} 145 for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']: 146 try: 147 data = unicode(obj.__getattribute__(field)) 148 simplejson.dumps(data) # this will fail on non-encodable values, like other classes 149 fields[field] = data 150 except Exception: 151 fields[field] = None 152 # a json-encodable dict 153 return fields 154 155 if isinstance(obj, datetime): 156 return obj.__str__() 157 return simplejson.JSONEncoder.default(self, obj) 158 159 def json_dumps_time(json,**kwargs): 160 """ 161 获取json串,带time 162 :param json: 163 :param kwargs: 164 :return: 165 """ 166 return simplejson.dumps(json,cls=DateJsonEncoder, **kwargs) 167 168 def json_dumps_alchemy(json,**kwargs): 169 return simplejson.dumps(json, cls=AlchemyEncoder, **kwargs) 170 171 def json_load(str_json): 172 return simplejson.loads(str_json)