def lookup_common_fields(values, to_translate, ignore_key=None, is_field_type=False): result = defaultdict(dict) dict_key = 'models' if is_field_type: dict_key = 'fieldTypes' for name, name_list in values.items(): if not name_list: continue all_keys = set() for k in name_list: all_keys.update(k.keys()) if ignore_key in all_keys: all_keys.remove(ignore_key) for key in all_keys: check_translation = None if key in to_translate: check_translation = to_translate[key] value = MARKER value_idx = None for i, name_options in enumerate(name_list): other_value = name_options.get(key, MARKER) if other_value is MARKER: value_idx = None break elif value is MARKER: value = other_value value_idx = i elif not different_values(value, other_value): if check_translation: idx = lookup_id(check_translation, name_options) if idx is not None: check_translation.pop(idx) name_options.pop(key) if value_idx is not None: details = name_list[value_idx] if check_translation: idx = lookup_id(check_translation, details) if idx is not None: check_translation.pop(idx) to_translate[dict_key][name].add(key) result[name][key] = details.pop(key) return result
def construct_structure(self, schema, values, fields, first_value=False): if isinstance(schema.typ, Sequence): result = [] if values is None: return result elif values is null: return [] child = schema.children[0] for value in values: child_value = self.construct_structure(child, value, fields) if child_value is not None: result.append(child_value) return result elif isinstance(schema.typ, Tuple): raise NotImplementedError('Tuple type need to be implemented') elif isinstance(schema.typ, Mapping): result = {} if values is None or (values is null and not first_value): return result if isinstance(values, dict): get_value = values.get else: get_value = lambda k, d=None: getattr(values, k, d) for child in schema.children: if child.name not in fields: continue child_values = get_value(child.name, child.default) value = self.construct_structure(child, child_values, fields[child.name]) add_value = bool(value is not None or child.missing is not drop) if not add_value and hasattr(child, 'use_when'): for key, compare_value in child.use_when.items(): if different_values(get_value(key), compare_value): add_value = False break else: add_value = True if add_value: result[self.encode_key(child.name)] = value return result else: if values is not None: values = schema.serialize(values) if values is null: return None elif values is not None: if isinstance(schema.typ, Number): return schema.typ.num(values) elif isinstance(schema.typ, Boolean): return asbool(values) else: return values else: return values
def construct_structure(self, schema, values, fields, first_value=False): if isinstance(schema.typ, Sequence): result = [] if values is None: return result elif values is null: return [] child = schema.children[0] for value in values: child_value = self.construct_structure(child, value, fields) if child_value is not None: result.append(child_value) return result elif isinstance(schema.typ, Tuple): raise NotImplementedError('Tuple type need to be implemented') elif isinstance(schema.typ, Mapping): result = {} if values is None or (values is null and not first_value): return result if isinstance(values, dict): get_value = values.get else: get_value = lambda k, d=None: getattr(values, k, d) for child in schema.children: if child.name not in fields: continue child_values = get_value(child.name, child.default) value = self.construct_structure( child, child_values, fields[child.name]) add_value = bool(value is not None or child.missing is not drop) if not add_value and hasattr(child, 'use_when'): for key, compare_value in child.use_when.items(): if different_values(get_value(key), compare_value): add_value = False break else: add_value = True if add_value: result[self.encode_key(child.name)] = value return result else: if values is not None: values = schema.serialize(values) if values is null: return None elif values is not None: if isinstance(schema.typ, Number): return schema.typ.num(values) elif isinstance(schema.typ, Boolean): return asbool(values) else: return values else: return values
def update_core(self, core_name, values, update_inactives=False, filters=None): if not values: return False if update_inactives: active = None else: active = True table = CORE_TYPES[core_name]['table'] core_name_values = {} core_values = {} for key, value in values.items(): column = getattr(table, key) if isinstance(column, CoreColumnParent): core_values[key] = value else: core_name_values[key] = value updated = False if core_name_values: attributes = set(core_name_values.keys()) attributes.add('id_core') response = self.get_core(core_name, attributes, active=active, filters=filters) if not response: return False to_update = {} for key, value in core_name_values.items(): response_value = getattr(response, key) if different_values(value, response_value): to_update[key] = value if to_update: self.direct_update(table, table.id_core == response.id_core, to_update) self.flush() updated = True if core_values or updated: core_attributes = set(core_values.keys()) core_attributes.update(['start_date', 'end_date']) core_attributes.add('id_core') response = self.get_core(core_name, core_attributes, active=active, filters=filters) if not response: return False # Convert time zones if 'start_date' in core_values: start_date = core_values['start_date'] if isinstance(start_date, DATETIME) and start_date.utcoffset(): start_date = start_date.replace( tzinfo=None) + start_date.utcoffset() if self.application_time_zone: start_date = start_date + self.application_time_zone core_values['start_date'] = start_date if 'end_date' in core_values: end_date = core_values['end_date'] if isinstance(end_date, DATETIME) and end_date.utcoffset(): end_date = end_date.replace( tzinfo=None) + end_date.utcoffset() if self.application_time_zone: end_date = end_date + self.application_time_zone core_values['end_date'] = end_date to_update = {} for key, value in core_values.items(): response_value = getattr(response, key) if different_values(value, response_value): to_update[key] = value start_date = to_update.get('start_date', response.start_date) end_date = to_update.get('end_date', response.end_date) if start_date and end_date and end_date < start_date: message = u'Start date must be lower than end date' raise Error('start_date', message) if to_update or updated: # Prevent SQLAlchemy pre-executed queries to_update['updated_date'] = func.now() self.direct_update(Core, Core.id == response.id_core, to_update) self.flush() updated = True return updated
def update_core(self, core_name, values, update_inactives=False, filters=None): if not values: return False if update_inactives: active = None else: active = True table = CORE_TYPES[core_name]['table'] core_name_values = {} core_values = {} for key, value in values.items(): column = getattr(table, key) if isinstance(column, CoreColumnParent): core_values[key] = value else: core_name_values[key] = value updated = False if core_name_values: attributes = set(core_name_values.keys()) attributes.add('id_core') response = self.get_core( core_name, attributes, active=active, filters=filters) if not response: return False to_update = {} for key, value in core_name_values.items(): response_value = getattr(response, key) if different_values(value, response_value): to_update[key] = value if to_update: self.direct_update( table, table.id_core == response.id_core, to_update) self.flush() updated = True if core_values or updated: core_attributes = set(core_values.keys()) core_attributes.update(['start_date', 'end_date']) core_attributes.add('id_core') response = self.get_core( core_name, core_attributes, active=active, filters=filters) if not response: return False # Convert time zones if 'start_date' in core_values: start_date = core_values['start_date'] if isinstance(start_date, DATETIME) and start_date.utcoffset(): start_date = start_date.replace(tzinfo=None) + start_date.utcoffset() if self.application_time_zone: start_date = start_date + self.application_time_zone core_values['start_date'] = start_date if 'end_date' in core_values: end_date = core_values['end_date'] if isinstance(end_date, DATETIME) and end_date.utcoffset(): end_date = end_date.replace(tzinfo=None) + end_date.utcoffset() if self.application_time_zone: end_date = end_date + self.application_time_zone core_values['end_date'] = end_date to_update = {} for key, value in core_values.items(): response_value = getattr(response, key) if different_values(value, response_value): to_update[key] = value start_date = to_update.get('start_date', response.start_date) end_date = to_update.get('end_date', response.end_date) if start_date and end_date and end_date < start_date: message = u'Start date must be lower than end date' raise Error('start_date', message) if to_update or updated: # Prevent SQLAlchemy pre-executed queries to_update['updated_date'] = func.now() self.direct_update( Core, Core.id == response.id_core, to_update) self.flush() updated = True return updated