class BaseAdjunct: """ Any Adjunct data which does not translate into SQL, but rather adds data programmatically. Basic smart class for records() call. """ skip = False # if skip is true, this adjunct will not be actually processed. resolves_field = True # if resolves_field is true, this adjunct will be called for a single field with resolve() post_processing = False # if post_processing is true, this adjunct will in the end be called with dbdata, and be able to manipulate the whole dictionary. def resolve(self, model, dbdata): """ resolve returns the field value for one entry. """ raise NotImplementedError def post_process(self, model, dbdata): """ if you have post_processing on True, this needs to be implemented. has to return either a new dictionary to use in initialization of an object, or None. """ raise NotImplementedError def values_field(self): """ return a field for the values operator. if you return a string, it will be added to values as args. if you return a tuple, it will be added to values as kwargs. """ return None class Adjunct(BaseAdjunct): """ value function that adds data, without SQL handling. """ def __init__(self, value=None): self.value = value def resolve(self, model, dbdata): return self.value class Lambda(Adjunct): """ adjunct value that returns a field value with a callback. """ def __init__(self, callback): self.callback = callback if callable(callback) else None def resolve(self, model, dbdata): # at this point i could check if callback needs 0-2 arguments and decide the call. if self.callback: return self.callback(dbdata) class Skip(BaseAdjunct): """ Skips this key from being retrieved from the database or used in the dataclass instantiation """ skip = True resolves_field = False class Callback(BaseAdjunct): """ calls a callback which can modify the whole initialization dictionary. """ resolves_field = False post_processing = True def __init__(self, callback): self.callback = callback def post_process(self, model, dbdata): if self.callback: return self.callback(dbdata)