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)