Search code examples
python-2.7flaskflask-sqlalchemyflask-restplus

sqlalchemy.orm.exc.UnmappedInstanceError: Class '__main__.User' is not mapped on Flask-SQLAlchemy


I just got a problem when implementing Flask-SQLAlchemy to my Flask-Restplus. It consistently show an error:

sqlalchemy.orm.exc.UnmappedInstanceError: Class '__main__.User' is not mapped

The code I've written below is the simplified version (1 file) of the Flask-Restplus example project on github: https://github.com/postrational/rest_api_demo

I've checked again and again, but have no idea why the error still appears.

Here is my code:

from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
from flask_restplus import Resource, Api, fields

app = Flask(__name__)
api = Api(app, version='v0.1')
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)

ns = api.namespace('users', description='User API')

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(80))
    password = db.Column(db.String(80))

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

    def __repr__(self):
        return '<User %s>' % self.email


user = api.model('user', {
    "id": fields.Integer(readOnly=True),
    "email": fields.String(required=True),
    "password": fields.String(required=True),
})


def create_user(data):
    email = data.get('email')
    password = data.get('password')

    user = User(email, password)

    db.session.add(user)
    db.session.commit()

def update_user(user_id, data):
    user = User.query.filter(User.id == user_id).first()
    user.email = data.get('email')
    user.password = data.get('password')

    db.session.add(user)
    db.session.commit()

def delete_user(user_id):
    user = User.query.filter(User.id == user_id).first()

    db.session.delete(user)
    db.session.commit()


@ns.route('/')
class UserList(Resource):
    @ns.marshal_list_with(user)
    def get(self):
        users = User.query.all()
        return users

    @ns.marshal_with(user)
    @ns.expect(user)
    def post(self):
        data = request.json
        create_user(data)
        return None, 201

@ns.route('/<int:id>')
class User(Resource):
    @ns.marshal_with(user)
    def get(self, id):
        user = User.query.filter(User.id == id).first()
        return user

    @ns.expect(user)
    @ns.marshal_with(user)
    def put(self, id):
        data = request.json
        user = update_user(id, data)
        return None, 204

    def delete(self, id):
        delete_user(id)
        return None, 204


db.create_all()

user = User(email= 'saffsds@gmail.com', password= '4324dsfdsfa')
db.session.add(user)
db.session.commit()

user = User(email= 'sdfsdf@gmail.com', password= '5435rs')
db.session.add(user)
db.session.commit()

users = User.query.all()
print users

if __name__ == "__main__":

    app.run(debug=True)

Is there anything I missed on the code? I use python2.7 anyway..


Solution

  • im pretty sure its because you are overloading User.__init__, but you didnt call super, so do this and see if it maps:

    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        email = db.Column(db.String(80))
        password = db.Column(db.String(80))
    
        def __init__(self, email, password):
            self.email = email
            self.password = password
            super(User,self).__init__()
    
        def __repr__(self):
            return '<User %s>' % self.email