marshmallow-jsonapi
marshmallow-jsonapi copied to clipboard
How do I get many rows with links?
Help!
burned many hours and brain cells trying to figure this out... I have an 'id' key in my data.
Code
import datetime
import pprint
from marshmallow_jsonapi import Schema, fields
from marshmallow import post_dump
data = [{'id': 1,
'created_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595964),
'updated_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595965),
'description': 'NAN63831511',
'review_status_type': 1,
'user': 1,
'version': 1},
{'id': 4,
'created_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595964),
'updated_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595965),
'description': 'NAN73623423',
'review_status_type': 1,
'user': 3,
'version': 2},
{'id': 5,
'created_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595964),
'updated_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595965),
'description': 'NAN93623423',
'review_status_type': 1,
'user': 5,
'version': 2},
{'id': 2,
'created_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595964),
'updated_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595965),
'description': 'NAN63831511',
'review_status_type': 1,
'user': 1,
'version': 2},
{'id': 3,
'created_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595964),
'updated_at': datetime.datetime(2022, 6, 29, 19, 16, 18, 595965),
'description': 'NAN63838745',
'review_status_type': 1,
'user': 1,
'version': 2}]
url_ = 'http://127.0.0.1/review/{id}'
many_url_ = 'http://127.0.0.1/reviews/{id}'
class ReviewSchema(Schema):
id = fields.Integer(dump_only=True)
created_at = fields.DateTime(format="iso")
updated_at = fields.DateTime(format="iso")
description = fields.String()
review_status_type_id = fields.Integer()
user_id = fields.Integer()
version = fields.Integer()
class Meta:
many = True
type_ = "reviews" # required!
self_view = "review_detail"
self_view_kwargs = {"id": "<id>"}
self_view_many = "reviews_list"
self_url_kwargs = {'id': "<id>"}
self_url = url_
self_url_many = many_url_
@post_dump
def fix_datetimes(self, data, **kwargs):
# print(f"@post_dump data = {data}")
data['created_at'] += 'Z'
data['updated_at'] += 'Z'
return data
# dump single row
print(f"\n{25*'*'} ONE ROW {25*'*'}\n")
resp = ReviewSchema().dump(data[2])
pprint.pprint(resp)
print(f"\n{25*'*'} ONE ROW {25*'*'}\n")
# dump rows
print(f"\n{25*'*'} MANY ROWS {25*'*'}\n")
resp = ReviewSchema(many=True).dump(data)
pprint.pprint(resp)
print(f"\n{25*'*'} MANY ROWS {25*'*'}\n")
Output
************************* ONE ROW *************************
{'data': {'attributes': {'created_at': '2022-06-29T19:16:18.595964Z',
'description': 'NAN93623423',
'updated_at': '2022-06-29T19:16:18.595965Z',
'version': 2},
'id': 5,
'links': {'self': 'http://127.0.0.1/review/5'},
'type': 'reviews'},
'links': {'self': 'http://127.0.0.1/review/5'}}
************************* ONE ROW *************************
************************* MANY ROWS *************************
Traceback (most recent call last):
File "/Users/user/PycharmProjects/pee-wee-testing/many_rows.py", line 83, in <module>
resp = ReviewSchema(many=True).dump(data)
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py", line 560, in dump
result = self._invoke_dump_processors(
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py", line 1071, in _invoke_dump_processors
data = self._invoke_processors(
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py", line 1225, in _invoke_processors
data = processor(data, many=many, **kwargs)
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py", line 128, in format_json_api_response
ret = self.wrap_response(ret, many)
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py", line 415, in wrap_response
top_level_links = self.get_top_level_links(data, many)
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py", line 393, in get_top_level_links
self_link = self.generate_url(self.opts.self_url_many)
File "/Users/user/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py", line 422, in generate_url
return link.format_map(kwargs) if link else None
KeyError: 'id'
Process finished with exit code 1
When I run it in a jupyter notebook I get some extra error information which may be helpful:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Input In [70], in <cell line: 4>()
2 # dump many rows
3 rs = ReviewSchema(many=True)
----> 4 resp = rs.dump(data)
5 print(resp)
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py:560, in Schema.dump(self, obj, many)
557 result = self._serialize(processed_obj, many=many)
559 if self._has_processors(POST_DUMP):
--> 560 result = self._invoke_dump_processors(
561 POST_DUMP, result, many=many, original_data=obj
562 )
564 return result
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py:1071, in Schema._invoke_dump_processors(self, tag, data, many, original_data)
1062 def _invoke_dump_processors(
1063 self, tag: str, data, *, many: bool, original_data=None
1064 ):
1065 # The pass_many post-dump processors may do things like add an envelope, so
1066 # invoke those after invoking the non-pass_many processors which will expect
1067 # to get a list of items.
1068 data = self._invoke_processors(
1069 tag, pass_many=False, data=data, many=many, original_data=original_data
1070 )
-> 1071 data = self._invoke_processors(
1072 tag, pass_many=True, data=data, many=many, original_data=original_data
1073 )
1074 return data
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow/schema.py:1225, in Schema._invoke_processors(self, tag, pass_many, data, many, original_data, **kwargs)
1223 data = processor(data, original_data, many=many, **kwargs)
1224 else:
-> 1225 data = processor(data, many=many, **kwargs)
1226 return data
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py:128, in Schema.format_json_api_response(self, data, many, **kwargs)
123 """Post-dump hook that formats serialized data as a top-level JSON API object.
124
125 See: http://jsonapi.org/format/#document-top-level
126 """
127 ret = self.format_items(data, many)
--> 128 ret = self.wrap_response(ret, many)
129 ret = self.render_included_data(ret)
130 ret = self.render_meta_document(ret)
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py:415, in Schema.wrap_response(self, data, many)
412 # self_url_many is still valid when there isn't any data, but self_url
413 # may only be included if there is data in the ret
414 if many or data:
--> 415 top_level_links = self.get_top_level_links(data, many)
416 if top_level_links["self"]:
417 ret["links"] = top_level_links
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py:393, in Schema.get_top_level_links(self, data, many)
391 if many:
392 if self.opts.self_url_many:
--> 393 self_link = self.generate_url(self.opts.self_url_many)
394 else:
395 if self.opts.self_url:
File ~/PycharmProjects/pee-wee-testing/venv/lib/python3.10/site-packages/marshmallow_jsonapi/schema.py:422, in Schema.generate_url(self, link, **kwargs)
420 def generate_url(self, link, **kwargs):
421 """Generate URL with any kwargs interpolated."""
--> 422 return link.format_map(kwargs) if link else None
KeyError: 'id'