Пример #1
0
    def update(self, obj, set_fields = None, unset_fields = None, update_obj = True):
        """
        We return the result of the save method (updates are not yet implemented here).
        """
        if set_fields:
            if isinstance(set_fields,(list,tuple)):
                set_attributes = {}
                for key in set_fields:
                    try:
                        set_attributes[key] = get_value(obj,key)
                    except KeyError:
                        pass
            else:
                set_attributes = set_fields
        else:
            set_attributes = {}
        if unset_fields:
            unset_attributes = unset_fields
        else:
            unset_attributes = []

        self.call_hook('before_update',obj,set_attributes,unset_attributes)

        if update_obj:
            for key,value in set_attributes.items():
                set_value(obj,key,value)
            for key in unset_attributes:
                delete_value(obj,key)

        return self.save(obj,call_hook = False)
Пример #2
0
        def serialize_fields(fields):
            if isinstance(fields, (list, tuple)):
                update_dict = {}
                for key in fields:
                    try:
                        update_dict[key] = get_value(obj, key)
                    except KeyError:
                        pass
            elif isinstance(fields, dict):
                update_dict = fields.copy()
            else:
                raise TypeError("fields must be a list/tuple!")

            return update_dict
Пример #3
0
        def serialize_fields(fields):


            if isinstance(fields, (list,tuple)):
                update_dict = {}
                for key in fields:
                    try:
                        update_dict[key] = get_value(obj,key)
                    except KeyError:
                        pass
            elif isinstance(fields,dict):
                update_dict = fields.copy()
            else:
                raise TypeError("fields must be a list/tuple!")

            return update_dict
Пример #4
0
    def get_objects(self):

        def build_field_map(params,path = None,current_map = None):

            def m2m_o2m_getter(join_params,name,pk_key):

                def f(d,obj):
                    pk_value = obj[pk_key]
                    try:
                        v = d[name]
                    except KeyError:
                        v = d[name] = OrderedDict()
                    if pk_value is None:
                        return None
                    if not pk_value in v:
                        v[pk_value] = {}
                    if not '__lazy__' in v[pk_value]:
                        v[pk_value]['__lazy__'] = join_params['lazy']
                    if not '__collection__' in v[pk_value]:
                        v[pk_value]['__collection__'] = join_params['collection']
                    return v[pk_value]

                return f

            def fk_getter(join_params,key):

                def f(d,obj):
                    pk_value = obj[join_params['table_fields']['pk']]
                    if pk_value is None:
                        return None
                    if not key in d:
                        d[key] = {}
                    v = d[key]
                    if not '__lazy__' in v:
                        v['__lazy__'] = join_params['lazy']
                    if not '__collection__' in v:
                        v['__collection__'] = join_params['collection']
                    return v

                return f

            if current_map is None:
                current_map = {}
            if path is None:
                path = []
            for key,field in params['table_fields'].items():
                if key in params['joins']:
                    continue
                current_map[field] = path+[key]
            for name,join_params in params['joins'].items():
                if name in current_map:
                    del current_map[name]
                if isinstance(join_params['relation']['field'],(ManyToManyField,OneToManyField)):
                    build_field_map(join_params,path+[m2m_o2m_getter(join_params,name,
                                                                 join_params['table_fields']['pk'])],current_map)
                else:
                    build_field_map(join_params,path+[fk_getter(join_params,name),],current_map)
            return current_map

        def replace_ordered_dicts(d):
            for key,value in d.items():
                if isinstance(value,OrderedDict):
                    replace_ordered_dicts(value)
                    d[key] = list(value.values())
                elif isinstance(value,dict):
                    d[key] = replace_ordered_dicts(value)
            return d

        s = self.get_select()

        field_map = build_field_map(self.include_joins)

        with self.backend.transaction():
            try:
                result = self.backend.connection.execute(s)
                if result.returns_rows:
                    objects = list(result.fetchall())
                else:
                    objects = []
            except sqlalchemy.exc.ResourceClosedError:
                objects = None
                raise

        #we "fold" the objects back into one list structure
        self.objects = []
        pks = []

        unpacked_objects = OrderedDict()
        for obj in objects:
            if not obj['pk'] in unpacked_objects:
                unpacked_objects[obj['pk']] = {'__lazy__' : self.include_joins['lazy'],
                                               '__collection__' : self.include_joins['collection']}
            unpacked_obj = unpacked_objects[obj['pk']]
            for key,path in field_map.items():
                d = unpacked_obj
                for element in path[:-1]:
                    if callable(element):
                        d = element(d,obj)
                        if d is None:
                            break
                    else:
                        d = get_value(d,element,create = True)
                else:
                    d[path[-1]] = obj[key]

        self.objects = [replace_ordered_dicts(unpacked_obj) for unpacked_obj in unpacked_objects.values()]
        self.pop_objects = self.objects[:]
Пример #5
0
    def get_objects(self):

        def build_field_map(params,path = None,current_map = None):

            def m2m_o2m_getter(join_params,name,pk_key):

                def f(d,obj):
                    pk_value = obj[pk_key]
                    try:
                        v = d[name]
                    except KeyError:
                        v = d[name] = OrderedDict()
                    if pk_value is None:
                        return None
                    if not pk_value in v:
                        v[pk_value] = {}
                    if not '__lazy__' in v[pk_value]:
                        v[pk_value]['__lazy__'] = join_params['lazy']
                    if not '__collection__' in v[pk_value]:
                        v[pk_value]['__collection__'] = join_params['collection']
                    return v[pk_value]

                return f

            def fk_getter(join_params,key):

                def f(d,obj):
                    pk_value = obj[join_params['table_fields']['pk']]
                    if pk_value is None:
                        d[key] = None #we set the key value to "None", to indicate that the FK is None
                        return None
                    if not key in d:
                        d[key] = {}
                    v = d[key]
                    if not '__lazy__' in v:
                        v['__lazy__'] = join_params['lazy']
                    if not '__collection__' in v:
                        v['__collection__'] = join_params['collection']
                    return v

                return f

            if current_map is None:
                current_map = {}
            if path is None:
                path = []
            for key,field in params['table_fields'].items():
                if key in params['joins']:
                    continue
                current_map[field] = path+[key]
            for name,join_params in params['joins'].items():
                if name in current_map:
                    del current_map[name]
                if isinstance(join_params['relation']['field'],(ManyToManyField,OneToManyField)):
                    build_field_map(join_params,path+[m2m_o2m_getter(join_params,name,
                                                                 join_params['table_fields']['pk'])],current_map)
                else:
                    build_field_map(join_params,path+[fk_getter(join_params,name),],current_map)
            return current_map

        def replace_ordered_dicts(d):
            for key,value in d.items():
                if isinstance(value,OrderedDict):
                    replace_ordered_dicts(value)
                    d[key] = list(value.values())
                elif isinstance(value,dict):
                    d[key] = replace_ordered_dicts(value)
            return d

        s = self.get_select()
        field_map = build_field_map(self.include_joins)

        with self.backend.transaction():
            try:
                result = self.backend.connection.execute(s)
                if result.returns_rows:
                    objects = list(result.fetchall())
                else:
                    objects = []
            except sqlalchemy.exc.ResourceClosedError:
                objects = None
                raise

        #we "fold" the objects back into one list structure
        self.objects = []
        pks = []

        unpacked_objects = OrderedDict()
        for obj in objects:
            if not obj['pk'] in unpacked_objects:
                unpacked_objects[obj['pk']] = {'__lazy__' : self.include_joins['lazy'],
                                               '__collection__' : self.include_joins['collection']}
            unpacked_obj = unpacked_objects[obj['pk']]
            for key,path in field_map.items():
                d = unpacked_obj
                for element in path[:-1]:
                    if callable(element):
                        d = element(d,obj)
                        if d is None:
                            break
                    else:
                        d = get_value(d,element,create=True)
                else:
                    d[path[-1]] = obj[key]

        self.objects = [replace_ordered_dicts(unpacked_obj) for unpacked_obj in unpacked_objects.values()]
        self.pop_objects = self.objects[:]