I face some troubles serializing an object with Marshmallow-sqlAlchemy.
I have two objects:
class Product(Model):
__tablename__: product_table_name
id = Column(Integer, primary_key=True)
name = Column(String)
class BasketItem(Model):
__tablename__: basket_item_table_name
id = Column(Integer, primary_key=True)
product_id = Column(
Integer, ForeignKey(f"{product_table_name}.id"), nullable=False
)
product = relationship("Product", foreign_keys="BasketItem.product_id")
And here is the marshmallow configuration:
class ProductBasketItemSchema(ModelSchema):
class Meta:
model = Product
fields = ("id", "name",)
class BasketItemSchema(ModelSchema):
class Meta:
model = BasketItem
include_relationships = True
fields = ("id", "product",)
product: Nested(ProductBasketItemSchema, many=False)
But the output of the basket_item_schema.dump(items)
only prints the ID of the products, not the content:
[{'id': 1, 'product': 123}]
instead of
[{'id': 1, 'product': {'id': 123, 'name': 'first'}}]
I think the problem is with the Schema declaration because I can access all the fields of the product before dumping it.
Am I missing something?
After debugging the Marshmallow library, I came into a deadend.
This can't be done because I'm trying to show the parent from the chid object. This can only be done for one-to-many or many-to-many but not for many-to-one relationships.
To do so, I've used a custom marshmallow mapper with Schema
(instead of ModelSchema
) as follows:
class ProdcutField(Field):
def __init__(self, **kwargs):
self.schema = ProductBasketItemSchema()
super().__init__(**kwargs)
def _serialize(self, value, attr, obj, **kwargs):
return self.schema.dump(value)
class BasketItemSchema(Schema):
id = fields.Integer()
product = ProductField()
When using ModelSchema
from marshmallow_sqlalchemy, the fields are mapped automatically and it checks the type of relationship. And for many-to-one, it only serialize the id of the object. I've been looking if I can override some functions, but it can't be done this way, so I implemented it manually as shown above.
I hope this will help somebody else.