PUT request not working, Flask-RESTful, SQLAlchemy

4k views Asked by At

I believe the issue is with committing the changes to the database (3rd to last line: db.session.commit()). For example take a user: username="Foo", email="[email protected]". If in the PUT request body I put {"email":"[email protected]"}, printing 'user.email' after the assignment reveals that the value is in fact changed. Afterwards however, upon querying the database the email remains unchanged. Anyway I'm really having trouble figuring out what I'm missing, so any help is appreciated!

class UserAPI(Resource):
    def __init__(self):
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('username', type=str, location='json')
        self.parser.add_argument('email', type=str, location='json')
        self.parser.add_argument('password', type=str, location='json')
        super(UserAPI, self).__init__()

    def put(self, id): 
        # Not working
        user = User.query.filter_by(id=id).first()
        if user is not None:
            args = self.parser.parse_args()
            for key, value in args.items():
                if args[key] is not None:
                    user.key = value
            db.session.commit()
            return {"user": marshal(user,user_field) }
        return {"error": "User not found"}, 404
2

There are 2 answers

0
jonafato On BEST ANSWER

Change user.key = value to setattr(user, key, value).

Instead of setting the attribute you want here (user.email) you're setting user.key. Because user.key is probably not a database column field (and certainly not the one you intend to set), the changes are not serialized to the database when db.session.commit() is called.

0
Pranay Khilari On

user.key will not work because while looping args we get string representation of key and value. If we do class_instance_name.key it will not point to attribute name as key is not attribute name it is a string only.

ex - here user.key is like user.'username' so it should not work.

use setattr(user, key, value) instead