improve speed of json mixin, add alternate for inserting to history
This commit is contained in:
Родитель
83c2d581f1
Коммит
3f8d225a3e
|
@ -32,7 +32,7 @@ OAuth authorization api.
|
|||
@json_exception_response
|
||||
def get(self, domain=None):
|
||||
keys = [k for k in session.get('account_keys', '').split(',') if k]
|
||||
return [session[k].get('profile') for k in keys]
|
||||
return [p for p in [session[k].get('profile') for k in keys] if p]
|
||||
|
||||
def signout(self):
|
||||
domain = request.params.get('domain')
|
||||
|
|
|
@ -98,6 +98,15 @@ The 'send' namespace is used to send updates to our supported services.
|
|||
# create a new record in the history table.
|
||||
assert result
|
||||
if asbool(config.get('history_enabled', True)):
|
||||
# this is faster, but still want to look further into SA perf
|
||||
#data = {
|
||||
# 'json_attributes': json.dumps(dict(request.POST)),
|
||||
# 'account_id': acct.get('id'),
|
||||
# 'published': UTCDateTime.now()
|
||||
#}
|
||||
#Session.execute("INSERT DELAYED INTO history (json_attributes, account_id, published) VALUES (:json_attributes, :account_id, :published)",
|
||||
# data)
|
||||
|
||||
history = History()
|
||||
history.account_id = acct.get('id')
|
||||
history.published = UTCDateTime.now()
|
||||
|
|
|
@ -6,42 +6,27 @@
|
|||
import json
|
||||
from sqlalchemy.orm.interfaces import MapperExtension, EXT_CONTINUE
|
||||
from sqlalchemy import Column, Text
|
||||
from sqlalchemy import types
|
||||
|
||||
# A mapper extension to help us with 'expandos' magic - ensures that expando
|
||||
# attributes set via normal 'object.expando=value' syntax is reflected
|
||||
# back into the json_attributes column.
|
||||
class _ExpandoFlushingExtension(MapperExtension):
|
||||
def before_insert(self, mapper, connection, instance):
|
||||
instance._flush_expandos()
|
||||
return EXT_CONTINUE
|
||||
class Json(types.TypeDecorator, types.MutableType):
|
||||
impl=types.Text
|
||||
|
||||
before_update = before_insert
|
||||
def process_bind_param(self, value, dialect):
|
||||
return json.dumps(value)
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
return json.loads(value)
|
||||
|
||||
# The actual mixin class
|
||||
class JsonExpandoMixin(object):
|
||||
__mapper_args__ = {'extension': _ExpandoFlushingExtension()}
|
||||
json_attributes = Column(Text)
|
||||
|
||||
# Methods for providing 'expandos' via the json_attributes field.
|
||||
def _get_expando_namespace(self):
|
||||
if '_expando_namespace' not in self.__dict__:
|
||||
assert '_orig_json' not in self.__dict__
|
||||
attrs = self.json_attributes
|
||||
self.__dict__['_orig_json'] = attrs
|
||||
if not attrs:
|
||||
_expando_namespace = {}
|
||||
else:
|
||||
_expando_namespace = json.loads(attrs)
|
||||
self.__dict__['_expando_namespace'] = _expando_namespace
|
||||
return self.__dict__['_expando_namespace']
|
||||
json_attributes = Column(Json)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name.startswith('_'):
|
||||
raise AttributeError(name)
|
||||
# is it in the namespace?
|
||||
try:
|
||||
return self._get_expando_namespace()[name]
|
||||
return self.json_attributes[name]
|
||||
except KeyError:
|
||||
raise AttributeError(name)
|
||||
|
||||
|
@ -52,30 +37,12 @@ class JsonExpandoMixin(object):
|
|||
# assume it is an 'expando' object
|
||||
# Set json attributes to itself simply so the object is marked as
|
||||
# 'dirty' for subsequent updates.
|
||||
self.json_attributes = self.json_attributes
|
||||
self._get_expando_namespace()[name] = value
|
||||
self.json_attributes = self.json_attributes or {}
|
||||
self.json_attributes[name] = value
|
||||
|
||||
def __delattr__(self, name):
|
||||
try:
|
||||
del self._get_expando_namespace()[name]
|
||||
del self.json_attributes[name]
|
||||
self.json_attributes = self.json_attributes # to mark as dirty
|
||||
except KeyError:
|
||||
raise AttributeError("'%s' is not an 'expando' property" % (name,))
|
||||
|
||||
# Note that you should never need to call this function manually - a
|
||||
# mapper extension is defined above which calls this function before
|
||||
# the object is saved.
|
||||
def _flush_expandos(self):
|
||||
try:
|
||||
en = self.__dict__['_expando_namespace']
|
||||
except KeyError:
|
||||
# no property accesses at all
|
||||
return
|
||||
if self._orig_json != self.json_attributes:
|
||||
# This means someone used 'expandos' *and* explicitly set
|
||||
# json_attributes on the same object.
|
||||
raise ValueError("object's json_attributes have changed externally")
|
||||
self.json_attributes = None if not en else json.dumps(en)
|
||||
# and reset the world back to as if expandos have never been set.
|
||||
del self.__dict__['_orig_json']
|
||||
del self.__dict__['_expando_namespace']
|
||||
|
|
|
@ -28,10 +28,10 @@ class SerializerMixin(object):
|
|||
val = val.isoformat().split('.')[0].replace('+00:00','')+'Z'
|
||||
|
||||
if prop.key == 'json_attributes':
|
||||
propdict.update(json.loads(val))
|
||||
propdict.update(val)
|
||||
else:
|
||||
propdict[prop.key] = val
|
||||
elif prop.key != 'json_attributes':
|
||||
else:
|
||||
propdict[prop.key] = val
|
||||
|
||||
for val in self._rd_collection_to_dict('tags', fields):
|
||||
|
|
Загрузка…
Ссылка в новой задаче