docs: def fromdict(model, data, exclude=None, exclude_underscore=None,
               allow_pk=None, follow=None, include=None, only=None):
      """Update a model from a dict
  
      Works almost identically as :meth:`dictalchemy.utils.asdict`. However, it
      will not create missing instances or update collections.
  
      This method updates the following properties on a model:
  
      * Simple columns
      * Synonyms
      * Simple 1-m relationships
  
      :param data: dict of data
      :param exclude: list of properties that should be excluded
      :param exclude_underscore: If True underscore properties will be excluded,\
              if set to None model.dictalchemy_exclude_underscore will be used.
      :param allow_pk: If True any column that refers to the primary key will \
              be excluded. Defaults model.dictalchemy_fromdict_allow_pk or \
              dictable.constants.fromdict_allow_pk. If set to True a primary \
              key can still be excluded with the `exclude` parameter.
      :param follow: Dict of relations that should be followed, the key is the \
              arguments passed to the relation. Relations only works on simple \
              relations, not on lists.
      :param include: List of properties that should be included. This list \
              will override anything in the exclude list. It will not override \
              allow_pk.
      :param only: List of the only properties that should be set. This \
              will not override `allow_pk` or `follow`.
  
      :raises: :class:`dictalchemy.errors.DictalchemyError` If a primary key is \
              in data and allow_pk is False
  
      :returns: The model
  
      """
  
      follow = arg_to_dict(follow)
  
      info = inspect(model)
      columns = [c.key for c in info.mapper.column_attrs]
      synonyms = [c.key for c in info.mapper.synonyms]
      relations = [c.key for c in info.mapper.relationships]
      primary_keys = [c.key for c in info.mapper.primary_key]
  
      if allow_pk is None:
          allow_pk = getattr(model, 'dictalchemy_fromdict_allow_pk',
                             constants.default_fromdict_allow_pk)
  
      if only:
          valid_keys = only
      else:
          exclude = exclude or []
          exclude += getattr(model, 'dictalchemy_exclude',
                             constants.default_exclude) or []
          if exclude_underscore is None:
              exclude_underscore = getattr(model,
                                           'dictalchemy_exclude_underscore',
                                           constants.default_exclude_underscore)
  
          if exclude_underscore:
              # Exclude all properties starting with underscore
              exclude += [k.key for k in info.mapper.attrs if k.key[0] == '_']
  
          include = (include or []) + (getattr(model,
                                               'dictalchemy_fromdict_include',
                                               getattr(model,
                                                       'dictalchemy_include',
                                                       None)) or [])
          valid_keys = [k for k in columns + synonyms
                        if k not in exclude] + include
  
      # Keys that will be updated
      update_keys = set(valid_keys) & set(data.keys())
  
      # Check for primary keys
      data_primary_key= update_keys & set(primary_keys)
      if len(data_primary_key) and not allow_pk:
          msg = ("Primary keys({0}) cannot be updated by fromdict."
                 "Set 'dictalchemy_fromdict_allow_pk' to True in your Model"
                 " or pass 'allow_pk=True'.").format(','.join(data_primary_key))
          raise errors.DictalchemyError(msg)
  
      # Update columns and synonyms
      for k in update_keys:
          setattr(model, k, data[k])
  
      # Update simple relations
      for (k, args) in follow.iteritems():
          if k not in data:
              continue
          if k not in relations:
              raise errors.MissingRelationError(k)
          rel = getattr(model, k)
          if hasattr(rel, 'fromdict'):
              rel.fromdict(data[k], **args)
  
      return model