2

I am trying to implement a restful API with Flask using flask-restful, flask-sqlalchemy and flask-marshmallow. I am aware there are many questions about this issue but I still can't figure it out. Solutions like using strict=True in marshmallow schemas or adding .data to user_schema.dump(result) don't let me see my result in the response body.

Here is my code :

# User.py file

from flask import jsonify, request
from flask_restful import Resource
from src import db
from src.models.user import User
from src.validation import UserSchema


class Users(Resource):
    def get(self):
        try:
            data = request.get_json()
            user = User.query.filter_by(email=data['email']).first()
            user_schema = UserSchema()
            result = user_schema.dump(user)
            return jsonify(result)
        except:
            return jsonify({'error_message': 'User not found'})

    def post(self):
        try:
            data = request.get_json()
            user = User(data["firstName"], data["lastName"],
                        data["email"], data["password"])
            db.session.add(user)
            db.session.commit()
            user_schema = UserSchema()
            result = user_schema.dump(user)
            return result
        except:
            return jsonify({'error_message': 'User already exists in database'})

The init.py file :

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api
from flask_marshmallow import Marshmallow


app = Flask(__name__)
app.config["DEBUG"] = True
app.config["SQLALCHEMY_ECHO"] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql:///gauss"

ma = Marshmallow(app)
api = Api(app)
db = SQLAlchemy(app)

from src import routes

The validation.py file :

from src import ma
from src.models.user import User

class UserSchema(ma.SQLAlchemySchema):
    class Meta:
        model = User

And the User.py schema for the database :

from src import db
from datetime import datetime

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    firstName = db.Column(db.String(20))
    lastName = db.Column(db.String(20))
    email = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(), nullable=False)
    createdAt = db.Column(db.DateTime, default=datetime.utcnow)

    def __init__(self, firstName, lastName, email, password):
        self.firstName = firstName
        self.lastName = lastName
        self.email = email
        self.password = password

I've been looking for solutions for a few days now and it seems that marshmallow returning empty json occures mostly when querying with the .all() method for instance, because marshmallow .dump() method misses the Many=True configuration.

I'm probably missing something but I can't wrap my head around it. Any help appreciated !

aaron
  • 39,695
  • 6
  • 46
  • 102

2 Answers2

0

i had the same problem, the solution to my problem was to change UserSchema(ma.SQLAlchemySchema): to UserSchema(ma.SQLAlchemyAutoSchema):

amin
  • 61
  • 1
  • 6
0

I had a similar issue.

Switching from

user_schema = UserSchema(Many=False)
...
user_schema.dump(user) ==> {}

to

users_schema = UserSchema(Many=True)
...
users_schema.dump(user) ==> {expected results}

worked for me.

Hippolyte BRINGER
  • 792
  • 1
  • 8
  • 30