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)
CodePudding user response:
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)