Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify behavior of attribute for load-only fields #2145

Closed
Defman21 opened this issue Jul 12, 2023 · 4 comments
Closed

Clarify behavior of attribute for load-only fields #2145

Defman21 opened this issue Jul 12, 2023 · 4 comments
Labels

Comments

@Defman21
Copy link

In the docs, it says that:

:param attribute: The name of the attribute to get the value from when serializing.

However, it also affects the deserialization part:

https://github.com/marshmallow-code/marshmallow/blob/dev/src/marshmallow/schema.py#L681

e.g.

from marshmallow import Schema, fields

class SomeSchema(Schema):
    field_dump = fields.Str(dump_only=True, attribute="some_name", data_key="field")
    field_load = fields.Str(load_only=True, attribute="field", data_key="some_other_name")

schema = SomeSchema()
schema.load({"some_other_name": "some field"}) # -> {"field": "some field"}
schema.dump({"some_name": "some value"}) # -> {"field": "some value"}

I've used data_key with different names to show distinction between attribute and data_key usage. My use case is:

  • I want to have {"some_field: "http://test"} as the result of Schema.dump(SomeThing(some_field_url="http://test"))
  • I want to have {"some_field": <BytesIO>} as the result of Schema.load({"some_field": "base64 representation of something"}).
@lafrech
Copy link
Member

lafrech commented Jul 12, 2023

You're right about the documentation issue. I think this was discussed a while back and I'm surprised it wasn't fixed already.

I'm afraid you're out of luck here because you'd need to set data_key to the same value for both fields, which is not allowed (to protect users from their own mistakes).

Your use case is a corner case that might not be worth removing that protection. It can be achieved by using two schemas, obviously. I don't see any other mean.

@Defman21
Copy link
Author

Defman21 commented Jul 12, 2023

I'm afraid you're out of luck here because you'd need to set data_key to the same value for both fields, which is not allowed (to protect users from their own mistakes).

Perhaps I'm missing something?

image
{'field': 'some field', 'id': 1}
{'field': 'some field', 'id': 2}

@lafrech lafrech added the docs label Jul 12, 2023
@lafrech
Copy link
Member

lafrech commented Jul 12, 2023

Oh, right. That's because we only check data_keys for fields that are not load-only. The rationale is that one may want to load the same data with multiple fields, while it would be wrong to dump multiple attributes to the same key.

Well, good for you. I'm labeling this a doc issue, then.

@lafrech
Copy link
Member

lafrech commented Aug 15, 2023

I just pushed a commit in dev with a phrasing that should fix this.

    :param data_key: The name of the dict key in the external representation, i.e.
        the input of `load` and the output of `dump`.
        If `None`, the key will match the name of the field.
    :param attribute: The name of the key/attribute in the internal representation, i.e.
        the output of `load` and the input of `dump`.
        If `None`, the key/attribute will match the name of the field.
        Note: This should only be used for very specific use cases such as
        outputting multiple fields for a single attribute, or using keys/attributes
        that are invalid variable names, unsuitable for field names. In most cases,
        you should use ``data_key`` instead.

Closing. Please comment if you think t is still ambiguous.

@lafrech lafrech closed this as completed Aug 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants