在 REST api 中通过 POST 传递时,数据库中存储的值不正确

Incorrect values stored in database when passed through POST in RESTapi

我在使用 RESTful API 中的 POST 命令将 json 数据保存到我的 postgres 数据库时遇到问题。数据被接受,但键值正在相互交换。我已经附加了 PUT 命令和生成的数据库。我的代码中有什么错误导致了这种奇怪的问题??

以下是用于管理我们网页的python文件(space省略了不必要的部分) 初始化.py

from flask import Flask, render_template, flash, request, url_for, redirect,session
from models import db, Users
from forms import SignupForm
from secrets import whole_string
import config
import logging
from logging.handlers import RotatingFileHandler
from flask_bcrypt import Bcrypt
from flask_restful import Resource, Api
from views import table_master

app = Flask(__name__)

db.init_app(app)
api = Api(app)
api.add_resource(table_master, '/api/master_animal/<cownumber>')
api.add_resource(table_master, '/api/master_animal/', endpoint = "cownumber")

if __name__ == '__main__':
    handler = RotatingFileHandler('barnyard.log', maxBytes=10000, backupCount=1)
    handler.setLevel(logging.INFO)
    app.logger.addHandler(handler)
    #app.run(debug = True)

观看次数.py

from flask import Blueprint, request, jsonify, make_response
from models import UsersSchema, db, Master_animal, Master_animal_Schema
from flask_restful import Api, Resource
from sqlalchemy.exc import SQLAlchemyError
from marshmallow import ValidationError
import sys

master_animal= Blueprint('master_animal', __name__) # Seems to only change the format of returned json data
schemaMaster = Master_animal_Schema()

# master_animal table
class table_master(Resource):

    def get(self, cownumber):
        master_animal_query = Master_animal.query.get_or_404(cownumber)
        #Serialize the query results in the JSON API format
        result = schemaMaster.dump(master_animal_query).data
        return result

    def post(self):
        raw_dict = request.get_json(force=True)
        master_dict = raw_dict['data']['attributes']
        print >> sys.stderr, "data {}".format(raw_dict)
        try:
                #Validate the data or raise a Validation error if
                schemaMaster.validate(master_dict)
                #Create a master object with the API data recieved
                master = Master_animal(master_dict['cownumber'], master_dict['weight'], master_dict['height'])
                master.add(master)
                query = Master_animal.query.all()
                results = schemaMaster.dump(query, many = True).data
                return results, 201


        except ValidationError as err:
                resp = jsonify({"error": err.messages})
                resp.status_code = 403
                return resp               

        except SQLAlchemyError as e:
                db.session.rollback()
                resp = jsonify({"error": str(e)})
                resp.status_code = 403
                return resp

模型.py

import sys

from flask import Flask
from flask_bcrypt import Bcrypt
from secrets import whole_string
from marshmallow_jsonapi import Schema, fields
from marshmallow import validate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.exc import SQLAlchemyError


app = Flask(__name__)
bcrypt = Bcrypt(app)
app.config['SQLALCHEMY_DATABASE_URI'] = whole_string
db = SQLAlchemy()


#Class to add, update and delete data via SQLALchemy sessions
class CRUD():   

    def add(self, resource):
        db.session.add(resource)
        return db.session.commit()   

    def update(self):
        return db.session.commit()

    def delete(self, resource):
        db.session.delete(resource)
        return db.session.commit()

class Master_animal(db.Model, CRUD):
    __tablename__ = 'master_animal'
    cownumber = db.Column(db.Text, primary_key = True)
    height = db.Column(db.Float)
    weight = db.Column(db.Float)

    def __init__(self, cownumber, height, weight):
        self.cownumber = cownumber
        self.height = height
        self.weight = weight

class Master_animal_Schema(Schema):
    not_blank = validate.Length(min=1, error ='Field cannot be blank')
    id = fields.Integer(dump_only=True) #WHY DOES THIS HAVE TO BE HERE???
    cownumber = fields.String(validate = not_blank)
    height = fields.Float(validate = not_blank)
    weight = fields.Float(validate = not_blank)

    # self links
    def get_top_level_links(self, data, many):
        print >> sys.stderr, "data {}".format(data) # print data to verify get request
        if many:
            self_link = "/master_animal/"
        else:
            self_link = "/master_animal/{}".format(data['attributes']['cownumber'])
        return {"self":self_link}
    class Meta:
        type_ = 'master_animal' 

在 postman 中使用 PUT

示例。com/api/master_animal/

正文:

{
  "data": {
    "attributes": {
      "cownumber": "1344",
      "height": 56,
      "weight": 230
    }}}

在我们的 postgreSQL 数据库中,身高和体重的值是互换的

barnyard=# Select * from master_animal;
 cownumber | height | weight
-----------+--------+--------
 1235      |    189 |     32
 1253      |    156 |     23
 1254      |    183 |     54
 1344      |    230 |     56

每个 PUT 命令都会产生这种格式。

我不知道为什么会这样或如何解决问题

我怀疑问题出在实例化 Master_animal 对象的地方。您几乎肯定会在那里使用关键字参数。

master = Master_animal(cownumer=master_dict['cownumber'], weight=master_dict['weight'], height=master_dict['height'])