serializationsqlalchemyflask-marshmallowmarshmallow-sqlalchemy

marshmallow - include_fk fail if foreign_key is not int


On serializing a related database entity with sql-alchemy and marshmallow I encountered following issue: On dumping this schema the debugger raises a ValueError with the message

    self._serialize(d, many=False)
    value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)
    return self._serialize(value, attr, obj, **kwargs)
    ret = self._format_num(value)  # type: _T
    return self.num_type(value)
ValueError: invalid literal for int() with base 10: 'sub'

It seems the library tries to cast the the key into an Integer. For readability reasons the key is a String in this case, so the cast obviously fails. Ist there a flag to avoid casting the foreign_key?

Here the models for reference: Parent Class

class Operation(db.Model):
    __tablename__ = "operation"
    key = db.Column(db.String(64), primary_key=True)
    label = db.Column(db.String(128), nullable=False)
    rules = db.relationship('app.models.rule.Rule', backref="operation")

Child Class

class Rule(db.Model):
    __tablename__ = 'rule'
    id = db.Column(db.Integer, primary_key=True, autoincrement="auto")
    operation_key = db.Column(db.Integer, ForeignKey('operation.key'))

class RuleSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Rule
        include_fk = True

Solution

  • Found a workaround. Adding a nested field with an only condition for the schema. Api. The serialised json nests the foreign key into a object. 'operation': {'key': 'sub'}

    class RuleSchema(ma.SQLAlchemyAutoSchema):
        class Meta:
            model = Rule
        #    include_fk = True
        operation = ma.Nested(OperationSchema, only=('key',))