Rest API POST 定义失败 | Python | Flask

huangapple go评论78阅读模式
英文:

Rest Api post definition failing | Python | Flask

问题

I am very new to python. I have basic idea with python and flask is totally new for me. Trying to learn rest api with python using flask. But, I am facing the issue while posting data. below are sample code and error. Please help me to fix this issue. Thanks in advance. I tried googling but did not get any solution.

Error while running

127.0.0.1 - - [03/Jan/2020 15:58:54] "POST /api/User HTTP/1.1" 500 -
  Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1997, in __call__
      return self.wsgi_app(environ, start_response)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1985, in wsgi_app
      response = self.handle_exception(e)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 273, in error_router
      return original_handler(e)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1540, in handle_exception
      reraise(exc_type, exc_value, tb)
    File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 32, in reraise
      raise value.with_traceback(tb)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1982, in wsgi_app
      response = self.full_dispatch_request()
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
      rv = self.handle_user_exception(e)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 273, in error_router
      return original_handler(e)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1517, in handle_user_exception
      reraise(exc_type, exc_value, tb)
    File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 32, in reraise
      raise value.with_traceback(tb)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
      rv = thispatch_request()
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1598, in dispatch_request
      return self.view_functions[rule.endpoint](**req.view_args)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 480, in wrapper
      resp = resource(*args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/flask/views.py", line 84, in view
      return thispatch_request(*args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 595, in dispatch_request
      resp = meth(*args, **kwargs)
    File "/Users/z0034ff/Documents/music/resources/Users.py", line 32, in post
      typeid=json_data['typeid'],
  TypeError: __init__() got an unexpected keyword argument 'fname'

File name: Model.py

from flask import Flask
  from marshmallow import Schema, fields, pre_load, validate
  from flask_marshmallow import Marshmallow
  from flask_sqlalchemy import SQLAlchemy


  ma = Marshmallow()
  db = SQLAlchemy()


  class Users(db.Model):
      __tablename__ = 'users'
      id = db.Column(db.Integer, primary_key=True)
      fname = db.Column(db.String(50), nullable=False)
      lname = db.Column(db.String(50), nullable=False)
      email = db.Column(db.String(100), nullable=False)
      phone = db.Column(db.String(50), nullable=False)
      typeid = db.Column(db.Integer, db.ForeignKey(
          'user_type.id', ondelete='CASCADE'), nullable=False)
      creation_date = db.Column(
          db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False)

      def __init__(self, users, typeid):
          self.users = users
          self.typeid = typeid

  class UsersSchema(ma.Schema):
      id = fields.Integer(dump_only=True)
      fname = fields.String(required=True, validate=validate.Length(1))
      lname = fields.String(required=True, validate=validate.Length(1))
      email = fields.String(required=True, validate=validate.Length(1))
      phone = fields.String(required=True, validate=validate.Length(10))
      typeid = fields.Integer(required=True)
      creation_date = fields.DateTime()

File name: Users.py

from flask import jsonify, request
  from flask_restful import Resource
  from Model import db, Users, UsersSchema

  users_schema = UsersSchema(many=True)
  user_schema = UsersSchema()


  class UsersResource(Resource):
      def get(self):
          users = Users.query.all()
          users = users_schema.dump(users).data
          return {"status": "success", "data": users}, 200

      def post(self):
          json_data = request.get_json(force=True)
          if not json_data:
              return {'message': 'No input data provided'}, 400
          # Validate and deserialize input
          data, errors = user_schema.load(json_data)
          if errors:
              return errors, 422
          user = Users.query.filter_by(email=data['email']).first()
          if user:
              return {'message': 'User already exists'}, 400
          print(json_data['fname'])
          user = Users(
              fname=json_data['fname'],
              lname=json_data['lname'],
              email=json_data['email'],
              phone=json_data['phone'],
              typeid=json_data['typeid'],
          )

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

          result = user_schema.dump(user).data

          return {"status": 'success', 'data': result}, 201
英文:

I am very new to python. I have basic idea with python and flask is totally new for me. Trying to learn rest api with python using flask. But, I am facing the issue while posting data. below are sample code and error. Please help me to fix this issue. Thanks in advance. I tried googling but did not get any solution.

Error while running

127.0.0.1 - - [03/Jan/2020 15:58:54] "POST /api/User HTTP/1.1" 500 -
  Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1997, in __call__
      return self.wsgi_app(environ, start_response)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1985, in wsgi_app
      response = self.handle_exception(e)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 273, in error_router
      return original_handler(e)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1540, in handle_exception
      reraise(exc_type, exc_value, tb)
    File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 32, in reraise
      raise value.with_traceback(tb)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1982, in wsgi_app
      response = self.full_dispatch_request()
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
      rv = self.handle_user_exception(e)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 273, in error_router
      return original_handler(e)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1517, in handle_user_exception
      reraise(exc_type, exc_value, tb)
    File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 32, in reraise
      raise value.with_traceback(tb)
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
      rv = self.dispatch_request()
    File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1598, in dispatch_request
      return self.view_functions[rule.endpoint](**req.view_args)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 480, in wrapper
      resp = resource(*args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/flask/views.py", line 84, in view
      return self.dispatch_request(*args, **kwargs)
    File "/usr/local/lib/python3.7/site-packages/flask_restful/__init__.py", line 595, in dispatch_request
      resp = meth(*args, **kwargs)
    File "/Users/z0034ff/Documents/music/resources/Users.py", line 32, in post
      typeid=json_data['typeid'],
  TypeError: __init__() got an unexpected keyword argument 'fname'

File name: Model.py

from flask import Flask
  from marshmallow import Schema, fields, pre_load, validate
  from flask_marshmallow import Marshmallow
  from flask_sqlalchemy import SQLAlchemy


  ma = Marshmallow()
  db = SQLAlchemy()


  class Users(db.Model):
      __tablename__ = 'users'
      id = db.Column(db.Integer, primary_key=True)
      fname = db.Column(db.String(50), nullable=False)
      lname = db.Column(db.String(50), nullable=False)
      email = db.Column(db.String(100), nullable=False)
      phone = db.Column(db.String(50), nullable=False)
      typeid = db.Column(db.Integer, db.ForeignKey(
          'user_type.id', ondelete='CASCADE'), nullable=False)
      creation_date = db.Column(
          db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False)

      def __init__(self, users, typeid):
          self.users = users
          self.typeid = typeid

  class UsersSchema(ma.Schema):
      id = fields.Integer(dump_only=True)
      fname = fields.String(required=True, validate=validate.Length(1))
      lname = fields.String(required=True, validate=validate.Length(1))
      email = fields.String(required=True, validate=validate.Length(1))
      phone = fields.String(required=True, validate=validate.Length(10))
      typeid = fields.Integer(required=True)
      creation_date = fields.DateTime()

File name: Users.py

from flask import jsonify, request
  from flask_restful import Resource
  from Model import db, Users, UsersSchema

  users_schema = UsersSchema(many=True)
  user_schema = UsersSchema()


  class UsersResource(Resource):
      def get(self):
          users = Users.query.all()
          users = users_schema.dump(users).data
          return {"status": "success", "data": users}, 200

      def post(self):
          json_data = request.get_json(force=True)
          if not json_data:
              return {'message': 'No input data provided'}, 400
          # Validate and deserialize input
          data, errors = user_schema.load(json_data)
          if errors:
              return errors, 422
          user = Users.query.filter_by(email=data['email']).first()
          if user:
              return {'message': 'User already exists'}, 400
          print(json_data['fname'])
          user = Users(
              fname=json_data['fname'],
              lname=json_data['lname'],
              email=json_data['email'],
              phone=json_data['phone'],
              typeid=json_data['typeid'],
          )

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

          result = user_schema.dump(user).data

          return {"status": 'success', 'data': result}, 201

答案1

得分: 1

不需要定义SQLAlchemy模型构造函数。SQLAlchemy文档 解释道:

> 使用声明式系统定义的User类
> 已经提供了一个构造函数(例如__init__()方法)
> 它会自动接受与我们映射的列匹配的关键字名称。
> 我们可以在类上定义任何明确的__init__()方法,
> 它会覆盖由声明式提供的默认方法。

Users.py的第27行,您尝试创建Users对象

          Users(
              fname=json_data['fname'],
              lname=json_data['lname'],
              email=json_data['email'],
              phone=json_data['phone'],
              typeid=json_data['typeid'],
          )

而在Model.py中,Users类的构造函数只接受2个参数。

  class Users(db.Model):
    ....

      def __init__(self, users, typeid):
          ...

这就是错误的来源:
TypeError: __init__() got an unexpected keyword argument 'fname'

移除__init__之后,应该可以正常工作。

英文:

It is not necessary to define SQLAlchemy model constructor. The SQLAlchemy docs explains:

> Our User class, as defined using the Declarative system,
> has been provided with a constructor (e.g. init() method)
> which automatically accepts keyword names that match the columns we’ve mapped.
> We are free to define any explicit init() method we prefer on our class,
> which will override the default method provided by Declarative.

In Users.py line 27 you try to create Users object

          Users(
              fname=json_data['fname'],
              lname=json_data['lname'],
              email=json_data['email'],
              phone=json_data['phone'],
              typeid=json_data['typeid'],
          )

Where in Model.py constructor of Users class takes only 2 arguments.

  class Users(db.Model):
    ....

      def __init__(self, users, typeid):
          ...

That's where the error comes from:
TypeError: __init__() got an unexpected keyword argument 'fname'

After removing __init__ it should work fine.

huangapple
  • 本文由 发表于 2020年1月3日 18:40:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/59577085.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定