Пример #1
0
 def to_dict(
     self,
     ignore: Union[str, List[str], Set[str]] = None,
     only: Union[str, List[str], Set[str]] = None,
 ) -> dict:
     ignore = make_ignore_rule_for_field(ignore)
     only = make_only_rule_for_field(only)
     return self.__to_dict(ignore, only)
Пример #2
0
def result_to_dict(result, ignore=None, only=None) -> dict:
    res = {}
    ignore_set = make_ignore_rule_for_field(ignore)
    only_set = make_only_rule_for_field(only)
    for key in result.keys():
        if key not in ignore_set:
            if only and key not in only_set:
                continue
            v = getattr(result, key)
            if isinstance(v, dt.datetime) and v.tzinfo is None:
                v = v.replace(tzinfo=local_tz_info)
            res[key] = v
    return res
Пример #3
0
def _update_model_by_dict(model,
                          dict_obj: dict,
                          ignore=None,
                          only=None,
                          __prefix=''):
    mapper = sqlalchemy.inspect(model).mapper
    col_attrs = mapper.column_attrs
    relationships = mapper.relationships
    ignore_set = make_ignore_rule_for_field(ignore)
    only_set = make_only_rule_for_field(only)
    for key in dict_obj:
        if key in col_attrs or key in relationships:
            if _in_set(__prefix, key, ignore_set):
                continue
            if only and not _in_set(__prefix, key, only_set):
                continue
            v = dict_obj[key]
            if key in relationships:
                if isinstance(v, dict):
                    obj = getattr(model, key)
                    if obj:
                        _update_model_by_dict(
                            obj,
                            v,
                            ignore=ignore_set,
                            only=only_set,
                            __prefix=_new_prefix(__prefix, key),
                        )
                        v = obj
                    else:
                        obj_cls = relationships[key].mapper.class_
                        v = _dict_to_model(
                            v,
                            obj_cls,
                            ignore=ignore_set,
                            only=only_set,
                            __prefix=_new_prefix(__prefix, key),
                        )
                elif isinstance(v, (list, set)):
                    # FIXME
                    raise RuntimeError(
                        f'do not support to update a list: "{_new_prefix(__prefix, key)}"'
                    )
            elif key in col_attrs:
                if isinstance(col_attrs[key].class_attribute.type,
                              sqlalchemy.DateTime):
                    v = convert_to_datetime(v)
            setattr(model, key, v)
Пример #4
0
def _dict_to_model(dict_obj: dict,
                   model_cls,
                   ignore=None,
                   only=None,
                   __prefix=''):
    mapper = sqlalchemy.inspect(model_cls).mapper
    col_attrs = mapper.column_attrs
    relationships = mapper.relationships
    ignore_set = make_ignore_rule_for_field(ignore)
    only_set = make_only_rule_for_field(only)
    kwargs = {}
    for key in dict_obj:
        if key in col_attrs or key in relationships:
            if _in_set(__prefix, key, ignore_set):
                continue
            if only and not _in_set(__prefix, key, only_set):
                continue
            v = dict_obj[key]
            if key in relationships:
                if isinstance(v, dict):
                    obj_cls = relationships[key].mapper.class_
                    v = _dict_to_model(
                        v,
                        obj_cls,
                        ignore=ignore_set,
                        only=only_set,
                        __prefix=_new_prefix(__prefix, key),
                    )
                elif isinstance(v, (list, set)):
                    obj_cls = relationships[key].mapper.class_
                    t = [
                        _dict_to_model(
                            obj,
                            obj_cls,
                            ignore=ignore_set,
                            only=only_set,
                            __prefix=_new_prefix(__prefix, key),
                        ) for obj in v
                    ]
                    v = t
            elif key in col_attrs:
                if isinstance(
                        getattr(model_cls, key).type, sqlalchemy.DateTime):
                    v = convert_to_datetime(v)
            kwargs[key] = v
    model = model_cls(**kwargs)
    return model
Пример #5
0
def _model_to_dict(model,
                   ignore=None,
                   only=None,
                   include=None,
                   __prefix='',
                   __exists=None) -> dict:
    if __exists is None:
        __exists = set()
    if model in __exists:
        raise DictRecursionError
    __exists.add(model)

    mapper = sqlalchemy.inspect(model).mapper
    col_attrs = mapper.column_attrs
    relationships = mapper.relationships

    d = {}
    ignore_set = make_ignore_rule_for_field(ignore)
    only_set = make_only_rule_for_field(only)
    include_set = make_include_rule_for_field(include)
    keys = list(col_attrs.keys())
    for k in relationships.keys():
        if _new_prefix(__prefix, k) in include_set:
            keys.append(k)
    for key in keys:
        if _in_set(__prefix, key, ignore_set):
            continue
        if only and not _in_set(__prefix, key, only_set):
            continue

        if key in col_attrs:
            v = getattr(model, key)
            if isinstance(v, dt.datetime) and v.tzinfo is None:
                v = v.replace(tzinfo=local_tz_info)
            d[key] = v
        elif key in relationships:
            if not hasattr(model, key):
                continue
            v = getattr(model, key)
            try:
                if v:
                    if isinstance(v, (list, set)):
                        t = [
                            _model_to_dict(
                                obj,
                                ignore=ignore_set,
                                only=only_set,
                                include=include_set,
                                __prefix=_new_prefix(__prefix, key),
                                __exists=__exists,
                            ) for obj in v
                        ]
                        v = t
                    else:
                        v = _model_to_dict(
                            v,
                            ignore=ignore_set,
                            only=only_set,
                            include=include_set,
                            __prefix=_new_prefix(__prefix, key),
                            __exists=__exists,
                        )
                d[key] = v
            except DictRecursionError:
                pass
    __exists.remove(model)
    return d
Пример #6
0
def test_make_ignore_rule():
    assert make_ignore_rule_for_field('a.b') == {'a.b'}
Пример #7
0
def _make_ignore_rule(ignore: Union[str, List[str], Set[str]]) -> dict:
    return _expand_rule_set(make_ignore_rule_for_field(ignore))