54 lines
1.6 KiB
Python
54 lines
1.6 KiB
Python
import sqlalchemy as sa
|
|
|
|
|
|
class ProxyDict(object):
|
|
def __init__(self, parent, collection_name, child_class, key_name):
|
|
self.parent = parent
|
|
self.collection_name = collection_name
|
|
self.child_class = child_class
|
|
self.key_name = key_name
|
|
self.cache = {}
|
|
|
|
@property
|
|
def collection(self):
|
|
return getattr(self.parent, self.collection_name)
|
|
|
|
def keys(self):
|
|
descriptor = getattr(self.child_class, self.key_name)
|
|
return [x[0] for x in self.collection.values(descriptor)]
|
|
|
|
def __contains__(self, key):
|
|
try:
|
|
return key in self.cache or self[key]
|
|
except KeyError:
|
|
return False
|
|
|
|
def fetch(self, key):
|
|
return self.collection.filter_by(**{self.key_name: key}).first()
|
|
|
|
def __getitem__(self, key):
|
|
if key in self.cache:
|
|
return self.cache[key]
|
|
|
|
session = sa.orm.object_session(self.parent)
|
|
if not session or not sa.orm.util.has_identity(self.parent):
|
|
value = self.child_class(**{self.key_name: key})
|
|
self.collection.append(value)
|
|
else:
|
|
value = self.fetch(key)
|
|
if not value:
|
|
value = self.child_class(**{self.key_name: key})
|
|
self.collection.append(value)
|
|
|
|
self.cache[key] = value
|
|
return value
|
|
|
|
def __setitem__(self, key, value):
|
|
try:
|
|
existing = self[key]
|
|
self.collection.remove(existing)
|
|
except KeyError:
|
|
pass
|
|
self.collection.append(value)
|
|
self.cache[key] = value
|