简体   繁体   中英

POST method in flask + mysql

When I run the POST method I get an error:

AttributeError: The 'dict' object has no 'create' attribute.

I've tried other ways to create data in the table, but they don't work either. GET, DELETE, PUT methods without any problem.

How can I fix this error? Or is there another way to make a POST request

Here is the code of my application:

from flask import Flask, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from marshmallow import fields
from marshmallow_sqlalchemy import SQLAlchemySchema

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password@localhost:5004/my_db'
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    firstname = db.Column(db.String(20))
    lastname = db.Column(db.String(20))
    timestamp = db.Column(db.DateTime, nullable=False)

    def create(self):
        db.session.add(self)
        db.session.commit()
        return self

    def __init__(self, firstname, lastname, timestamp):
        self.firstname = firstname
        self.lastname = lastname
        self.timestamp = timestamp

    def __repr__(self):
        return f'{self.id}'


db.create_all()


class UsersSchema(SQLAlchemySchema):
    class Meta(SQLAlchemySchema.Meta):
        model = User
        sql_session = db.session

    id = fields.Number(dump_only=True)
    firstname = fields.String(required=True)
    lastname = fields.String(required=True)
    timestamp = fields.String(required=True)


# working
@app.route('/users', methods=['GET'])
def index():
    get_users = User.query.all()
    user_schema = UsersSchema(many=True)
    users = user_schema.dump(get_users)
    return make_response(jsonify({"user": users}))


# doesn't work
@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    user_schema = UsersSchema(data)
    user = user_schema.load(data)
    result = user_schema.dump(user.crete())
    return make_response(jsonify({"user": result}), 200)


# working
@app.route('/users/<id>', methods=['GET'])
def get_user_by_id(id):
    get_user = User.query.get(id)
    user_schema = UsersSchema()
    user = user_schema.dump(get_user)
    return make_response(jsonify({"user": user}))


# working
@app.route('/users/<id>', methods=['PUT'])
def update_user_by_id(id):
    data = request.get_json()
    get_user = User.query.get(id)
    if data.get('firstname'):
        get_user.firstname = data['firstname']
    if data.get('lastname'):
        get_user.lastname = data['lastname']
    db.session.add(get_user)
    db.session.commit()
    user_schema = UsersSchema(only=['id', 'firstname', 'lastname'])
    user = user_schema.dump(get_user)

    return make_response(jsonify({"user": user}))


# working
@app.route('/users/<id>', methods=['DELETE'])
def delete_user_by_id(id):
    get_user = User.query.get(id)
    db.session.delete(get_user)
    db.session.commit()
    return make_response("", 204)


if __name__ == "__main__":
    app.run(debug=True)

I think you should reference this .

Without @post_load method, load() method will return deserialized result as dict type, not deserialized object. So create() method failed because dict type has no method create() .

So you should add @post_load method in UsersSchema class like below.

class UsersSchema(SQLAlchemySchema):
    class Meta(SQLAlchemySchema.Meta):
        model = User
        sql_session = db.session

    id = fields.Number(dump_only=True)
    firstname = fields.String(required=True)
    lastname = fields.String(required=True)
    timestamp = fields.String(required=True)
    
    # you should add this.
    @post_load
    def make_user(self, data, **kwargs):
        return User(**data)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM