diff --git a/pynamodb/models.py b/pynamodb/models.py
index a44d9e0..5e77a78 100644
--- a/pynamodb/models.py
+++ b/pynamodb/models.py
@@ -894,18 +894,20 @@ class Model(AttributeContainer):
         Reconstructs a model object from JSON.
         """
         hash_key, attrs = data
-        hash_keyname = cls._get_meta_data().hash_keyname
-        hash_key_attr = cls._get_attributes().get(cls._dynamo_to_python_attr(hash_keyname))
-        hash_key = hash_key_attr.deserialize(hash_key)
         range_key = attrs.pop('range_key', None)
         attributes = attrs.pop(pythonic(ATTRIBUTES))
+        hash_keyname = cls._get_meta_data().hash_keyname
+        hash_keytype = cls._get_meta_data().get_attribute_type(hash_keyname)
+        attributes[hash_keyname] = {
+            hash_keytype: hash_key
+        }
         if range_key is not None:
             range_keyname = cls._get_meta_data().range_keyname
             range_keytype = cls._get_meta_data().get_attribute_type(range_keyname)
             attributes[range_keyname] = {
                 range_keytype: range_key
             }
-        item = cls(hash_key)
+        item = cls()
         item._deserialize(attributes)
         return item
 
@@ -1260,14 +1262,13 @@ class Model(AttributeContainer):
 
         :param attrs: A dictionary of attributes to update this item with.
         """
-        for name, attr in attrs.items():
-            attr_name = self._dynamo_to_python_attr(name)
-            attr_instance = self._get_attributes().get(attr_name, None)
-            if attr_instance:
-                attr_type = ATTR_TYPE_MAP[attr_instance.attr_type]
-                value = attr.get(attr_type, None)
+        for name, attr in self._get_attributes().items():
+            value = attrs.get(attr.attr_name, None)
+            if value is not None:
+                value = value.get(ATTR_TYPE_MAP[attr.attr_type], None)
                 if value is not None:
-                    setattr(self, attr_name, attr_instance.deserialize(value))
+                    value = attr.deserialize(value)
+            setattr(self, name, value)
 
     def _serialize(self, attr_map=False, null_check=True):
         """

Model.refresh() doesn't respect attribute deletion
Let's consider this situation.
I have a model, like this:

```
class User(Model):
    name = UnicodeAttribute(hash_key=True)
    subscriptions = UnicodeSetAttribute()
```

Now, let's there is a user with just one subscription:

```
user = User(name='john', subscriptions=set(['news']))
user.save()
```

Then, in some other place of the program, we unsubscribe user from `news`:

```
u = User.get('john')
u.subscriptions.discard('news')
u.save()
```

And finally, in the initial object, we request a refresh:

```
user.refresh()
```

**What happens:**
`user` object has stale value of `subscriptions` field
**Expected behaviour:**
Disappeared value should be noticed, and `user.subscriptions` should be set to `None`.

**How to fix:**
The problem seems to be in `Model._deserialize` method. It walks over received data object and then for each field found in the model it updates that field. What would probably be better is to walk over model fields and update them from incoming data, or set them to `None` if not found.

diff --git a/pynamodb/tests/test_model.py b/pynamodb/tests/test_model.py
index 0f15b96..0e90d20 100644
--- a/pynamodb/tests/test_model.py
+++ b/pynamodb/tests/test_model.py
@@ -702,10 +702,12 @@ class ModelTestCase(TestCase):
 
         with patch(PATCH_METHOD) as req:
             req.return_value = GET_MODEL_ITEM_DATA
+            item.picture = b'to-be-removed'
             item.refresh()
             self.assertEqual(
                 item.custom_user_name,
                 GET_MODEL_ITEM_DATA.get(ITEM).get('user_name').get(STRING_SHORT))
+            self.assertIsNone(item.picture)
 
     def test_complex_key(self):
         """
@@ -4207,8 +4209,8 @@ class ModelTestCase(TestCase):
                 'mapy': {'M': {'baz': {'S': 'bongo'}}}
             }
         }
-        instance = ExplicitRawMapModel(map_attr=map_native)
-        instance._deserialize(map_serialized)
+        instance = ExplicitRawMapModel()
+        instance._deserialize({'map_attr': map_serialized})
         actual = instance.map_attr
         for k, v in six.iteritems(map_native):
             self.assertEqual(v, actual[k])

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
botocore==1.2.0
certifi==2021.5.30
docutils==0.18.1
importlib-metadata==4.8.3
iniconfig==1.1.1
jmespath==0.7.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
-e git+https://github.com/pynamodb/PynamoDB.git@f04c682242ef0b55feaa45af5048362942c898a2#egg=pynamodb
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.9.0.post0
six==1.9.0
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: PynamoDB
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - botocore==1.2.0
      - docutils==0.18.1
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jmespath==0.7.1
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - six==1.9.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/PynamoDB

pynamodb/tests/test_model.py::ModelTestCase::test_refresh
pynamodb/tests/test_model.py::ModelTestCase::test_batch_get pynamodb/tests/test_model.py::ModelTestCase::test_batch_write pynamodb/tests/test_model.py::ModelTestCase::test_batch_write_with_unprocessed pynamodb/tests/test_model.py::ModelTestCase::test_car_model_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_car_model_with_null_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_complex_key pynamodb/tests/test_model.py::ModelTestCase::test_complex_model_is_complex pynamodb/tests/test_model.py::ModelTestCase::test_complex_model_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_conditional_operator_map_attribute pynamodb/tests/test_model.py::ModelTestCase::test_count pynamodb/tests/test_model.py::ModelTestCase::test_count_no_hash_key pynamodb/tests/test_model.py::ModelTestCase::test_create_model pynamodb/tests/test_model.py::ModelTestCase::test_delete pynamodb/tests/test_model.py::ModelTestCase::test_delete_doesnt_do_validation_on_null_attributes pynamodb/tests/test_model.py::ModelTestCase::test_deserializing_map_four_layers_deep_works pynamodb/tests/test_model.py::ModelTestCase::test_deserializing_new_style_bool_false_works pynamodb/tests/test_model.py::ModelTestCase::test_deserializing_new_style_bool_true_works pynamodb/tests/test_model.py::ModelTestCase::test_deserializing_old_style_bool_false_works pynamodb/tests/test_model.py::ModelTestCase::test_deserializing_old_style_bool_true_works pynamodb/tests/test_model.py::ModelTestCase::test_dumps pynamodb/tests/test_model.py::ModelTestCase::test_explicit_raw_map_serialize_pass pynamodb/tests/test_model.py::ModelTestCase::test_filter_count pynamodb/tests/test_model.py::ModelTestCase::test_get pynamodb/tests/test_model.py::ModelTestCase::test_global_index pynamodb/tests/test_model.py::ModelTestCase::test_index_count pynamodb/tests/test_model.py::ModelTestCase::test_index_multipage_count pynamodb/tests/test_model.py::ModelTestCase::test_index_queries pynamodb/tests/test_model.py::ModelTestCase::test_invalid_car_model_with_null_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_invalid_map_model_raises pynamodb/tests/test_model.py::ModelTestCase::test_list_of_map_works_like_list_of_map pynamodb/tests/test_model.py::ModelTestCase::test_list_works_like_list pynamodb/tests/test_model.py::ModelTestCase::test_loads pynamodb/tests/test_model.py::ModelTestCase::test_loads_complex_model pynamodb/tests/test_model.py::ModelTestCase::test_local_index pynamodb/tests/test_model.py::ModelTestCase::test_model_attrs pynamodb/tests/test_model.py::ModelTestCase::test_model_subclass_attributes_inherited_on_create pynamodb/tests/test_model.py::ModelTestCase::test_model_with_invalid_data_does_not_validate pynamodb/tests/test_model.py::ModelTestCase::test_model_with_list pynamodb/tests/test_model.py::ModelTestCase::test_model_with_list_of_map pynamodb/tests/test_model.py::ModelTestCase::test_model_with_list_of_map_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_model_with_list_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_model_with_maps pynamodb/tests/test_model.py::ModelTestCase::test_model_with_maps_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_model_with_maps_with_nulls_retrieve_from_db pynamodb/tests/test_model.py::ModelTestCase::test_model_with_maps_with_pythonic_attributes pynamodb/tests/test_model.py::ModelTestCase::test_model_with_nulls_validates pynamodb/tests/test_model.py::ModelTestCase::test_model_works_like_model pynamodb/tests/test_model.py::ModelTestCase::test_multiple_indices_share_non_key_attribute pynamodb/tests/test_model.py::ModelTestCase::test_new_style_boolean_serializes_as_bool pynamodb/tests/test_model.py::ModelTestCase::test_old_style_boolean_serializes_as_bool pynamodb/tests/test_model.py::ModelTestCase::test_old_style_model_exception pynamodb/tests/test_model.py::ModelTestCase::test_overidden_defaults pynamodb/tests/test_model.py::ModelTestCase::test_overidden_session pynamodb/tests/test_model.py::ModelTestCase::test_overridden_attr_name pynamodb/tests/test_model.py::ModelTestCase::test_projections pynamodb/tests/test_model.py::ModelTestCase::test_query pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_greater_than_available_items_and_page_size pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_greater_than_available_items_multiple_page pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_greater_than_available_items_single_page pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_identical_to_available_items_single_page pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_less_than_available_and_page_size pynamodb/tests/test_model.py::ModelTestCase::test_query_limit_less_than_available_items_multiple_page pynamodb/tests/test_model.py::ModelTestCase::test_rate_limited_scan pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_as_sub_map pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_as_sub_map_deserialize pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_as_sub_map_from_raw_data_works pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_as_sub_map_serialize_pass pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_deserializes pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_from_raw_data_works pynamodb/tests/test_model.py::ModelTestCase::test_raw_map_serialize_fun_one pynamodb/tests/test_model.py::ModelTestCase::test_result_set_init pynamodb/tests/test_model.py::ModelTestCase::test_result_set_iter pynamodb/tests/test_model.py::ModelTestCase::test_save pynamodb/tests/test_model.py::ModelTestCase::test_scan pynamodb/tests/test_model.py::ModelTestCase::test_scan_limit pynamodb/tests/test_model.py::ModelTestCase::test_scan_limit_with_page_size pynamodb/tests/test_model.py::ModelTestCase::test_update pynamodb/tests/test_model.py::ModelTestCase::test_update_item pynamodb/tests/test_model.py::ModelInitTestCase::test_raw_map_attribute_with_dict_init pynamodb/tests/test_model.py::ModelInitTestCase::test_raw_map_attribute_with_initialized_instance_init pynamodb/tests/test_model.py::ModelInitTestCase::test_subclassed_map_attribute_with_dict_init pynamodb/tests/test_model.py::ModelInitTestCase::test_subclassed_map_attribute_with_initialized_instance_init pynamodb/tests/test_model.py::ModelInitTestCase::test_subclassed_map_attribute_with_map_attribute_member_with_initialized_instance_init pynamodb/tests/test_model.py::ModelInitTestCase::test_subclassed_map_attribute_with_map_attributes_member_with_dict_init
pynamodb/models.py
pynamodb/models.py