Flask sqlalchemy Marshmallow deserialize many to many ‘dict’ object has no attribute ‘_sa_instance_state’

  flask, flask-marshmallow, flask-sqlalchemy, python

I’m trying to user marshmallow’s .load() method to deserialize a json object on a POST request. But I keep running into this error 'dict' object has no attribute '_sa_instance_state' Users and Roles has a many to many relationship. .dump() on the schema works fine, but .load() can save all the other fields except the multiple roles. I’m trying to pass this in my json body.

{
    "last_name": "Fin",
    "roles": [{"id": 3, "role": "admin"}],
    "email": "[email protected]",
    "first_name": "Al",
    "access_id": "ec1235",
    "password": "1234567"
}

My user and Role models

user_role = db.Table('user_role',
                 db.Column('user_id', db.ForeignKey('user.id')),
                 db.Column('role_id', db.ForeignKey('role.id')),
                 db.Column('properties', JSONType),
                 )

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    access_id = db.Column(db.String(6), unique=True, nullable=False)
    email = db.Column(EmailType, unique=True, nullable=False)
    password = db.Column(db.String(80), nullable=False)
    roles = db.relationship('Role', secondary=user_role, backref='user', cascade="all")

class Role(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    role = db.Column(db.String(20), nullable=False)

My Schema

class RoleSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        fields = ("id", "role")
        model = Role

class UserSchema(ma.SQLAlchemyAutoSchema):
    roles = ma.Nested(RoleSchema, many=True)

    class Meta:
        load_instance = True
        fields = ("id", "first_name", "last_name", "access_id", "email", "roles, "password")
        model = User

Post request

    def post(self):
        try:
            body = request.get_json()
            user = user_schema.load(body)
            user.hash_password()
            db.session.add(user)
            db.session.commit()
            return {'id': str(user.id)}, 200
        except Exception as e:
            raise Exception("")

Source: Python Questions

LEAVE A COMMENT