Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

flask - Marshmallow for python giving ValueError: not enough values to unpack (expected 2, got 1)

I am using Marshmallow for serialization/deserialization purposes in the API I am building but I'm getting the above-stated error. Here are my Schema, Model, and Resource file for the same.

schemas/post.py

from marshmallow import Schema, fields, validate, post_dump

from schemas.user import UserSchema

class PostSchema(Schema):
    class Meta:
        ordered = True

    id = fields.Int(dump_only=True)
    body = fields.Str(required=True, validate=[validate.Length(max=500, min=1)])
    created_at = fields.DateTime(dump_only=True)
    updated_at = fields.DateTime(dump_only=True)
    author = fields.Nested(UserSchema, attribute='user', dump_only=True, only=['id', 'username'])

    @post_dump(pass_many=True)
    def wrap_output_with_envelope(self, data, many, **kwargs):
        if many:
            return {'data': data}
        return data

models/post.py

from database import db

class Post(db.Model):
    __tablename__ = 'post'

    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String, nullable=False)
    created_at = db.Column(db.DateTime(), nullable=False, server_default=db.func.now())
    updated_at = db.Column(db.DateTime(), nullable=False, server_default=db.func.now(), onupdate=db.func.now())
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    @classmethod
    def get_by_post_id(cls, id):
        return cls.query.filter_by(id=id).first()

    @classmethod
    def get_all_posts(cls):
        return cls.query.all()

    def data(self):
        return {'id': self.id, 'body': self.body, 'user_id': self.user_id}

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

and resources/post.py

from flask import request
from flask_restful import Resource
from http import HTTPStatus
from flask_jwt_extended import jwt_required, get_jwt_identity, jwt_optional

from models.post import Post
from schemas.post import PostSchema

post_schema = PostSchema()
post_list_schema = PostSchema(many=True)


class PostListResource(Resource):

    def get(self):
        posts = Post.get_all_posts()
        return post_list_schema.dump(posts), HTTPStatus.OK

    @jwt_required
    def post(self):
        json_data = request.get_json()
        current_user = get_jwt_identity()
        data, errors = post_schema.load(data=json_data)
        if errors:
            return {'message': "Validation errors", 'errors': errors}, HTTPStatus.BAD_REQUEST

        post = Post(**data)
        post.user_id = current_user
        post.save()

        return post_schema.dump(post), HTTPStatus.CREATED

I try sending the following JSON: {"body": "This is some text."} and the error I get is:

Traceback (most recent call last):
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask_restful\__init__.py", line 272, in error_router
    return original_handler(e)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask\_compat.py", line 38, in reraise
    raise value.with_traceback(tb)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask_restful\__init__.py", line 272, in error_router
    return original_handler(e)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask\_compat.py", line 38, in reraise
    raise value.with_traceback(tb)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskapp.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask_restful\__init__.py", line 468, in wrapper
    resp = resource(*args, **kwargs)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflaskviews.py", line 89, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask_restful\__init__.py", line 583, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:UsersUSER.virtualenvslogposts-QxTRQ3FGLibsite-packagesflask_jwt_extendedview_decorators.py", line 108, in wrapper
    return fn(*args, **kwargs)
  File "D:logposts
esourcespost.py", line 23, in post
    data, errors = post_schema.load(data=json_data)
ValueError: not enough values to unpack (expected 2, got 1)

Please help. Thanks!

question from:https://stackoverflow.com/questions/65830811/marshmallow-for-python-giving-valueerror-not-enough-values-to-unpack-expected

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You must have been following an outdated doc/tuto.

Since marshmallow 3, only data is returned. A ValidationError is raised in case of error.

Change

    data, errors = post_schema.load(data=json_data)
    if errors:
        return {'message': "Validation errors", 'errors': errors}, HTTPStatus.BAD_REQUEST

into

    try:
        data = post_schema.load(data=json_data)
    except ValidationError as exc:
        return {'message': "Validation errors", 'errors': exc.messages}, HTTPStatus.BAD_REQUEST

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...