Skip to content

Instantly share code, notes, and snippets.

@jnmclarty
Created March 18, 2015 03:43
Show Gist options
  • Save jnmclarty/50f0b9d22777a96e1704 to your computer and use it in GitHub Desktop.
Save jnmclarty/50f0b9d22777a96e1704 to your computer and use it in GitHub Desktop.
SQLA QuasiODict
class ProxyODict(object):
def __init__(self, parent, collection_name, childclass, ordername, keyname, valuename):
self.parent = parent
self.collection_name = collection_name
self.childclass = childclass
self.ordername = ordername
self.keyname = keyname
self.valuename = valuename
@property
def collection(self):
return getattr(self.parent, self.collection_name)
def keys(self):
# SQLAQ I feel like SQLA should be able to guarantee
# that these come back in the right order. I'm likely
# using python to sort something SQL could already have sorted for me.
descriptor = getattr(self.childclass, self.keyname)
orderer = getattr(self.childclass, self.ordername)
tmp = list(self.collection.values((orderer,descriptor)))
tmp.sort()
return [x[1] for x in tmp]
def __call__(self,valuename=None):
keys = self.keys()
val = valuename or self.valuename
values = [getattr(self[k],val) for k in keys]
d = dict(zip(keys,values))
return d
def __getitem__(self, obj):
if isinstance(obj,int):
x = self.collection.filter_by(**{self.ordername:obj}).first()
elif isinstance(obj,(list,tuple)) and len(obj) == 2:
x = self.collection.filter_by(**{self.ordername:obj[0],
self.keyname:obj[1]}).first()
elif isinstance(obj,str):
raise TypeError("ProxyODict key must be integer or list-like, found {}".format(type(obj)))
if x:
return x
else:
raise KeyError(obj)
def __setitem__(self, obj, value):
try:
existing = self[obj]
self.collection.remove(existing)
except KeyError:
pass
# at this point here, you need to pass the length of the collection and the value.
# But, but, what about changing the order? What about duplicated keys? ...TODO
self.collection.append(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment