简体   繁体   English

Python Flask SQLalchemy JSON POST错误

[英]Python Flask SQLalchemy JSON POST Error

I'm trying to post the following JSON and save to a MySQL database on a Flask server and Python 2.7, restless framework and SQLAlchemy with curl: 我正在尝试发布以下JSON并保存到Flask服务器和Python 2.7,不安框架和带有curl的SQLAlchemy上的MySQL数据库中:

curl -i -H "Accept: application/json" -X POST  -d '{"attribute_id": "1", "product_id": "44","text":"Something","language":"1"}' http://seroney-pc:5000/api/attributes

{
    "attribute_id": "1",
    "product_id": "44",
    "text": "Something",
    "language": "1"
}

My code is as follows: 我的代码如下:

from flask import Flask,request,jsonify, abort
from flask_sqlalchemy import SQLAlchemy
import flask_restless


app = Flask(__name__)
db = SQLAlchemy(app)
manager = flask_restless.APIManager(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:seroney@localhost:3306/test'


class Attributes(db.Model):
    __tablename__ = 'oc_product_attribute'
    product_id = db.Column(db.Integer,primary_key=True)
    attribute_id = db.Column(db.Integer,primary_key=True)
    language_id = db.Column(db.Integer,primary_key=True)
    text=db.Column(db.String)

@app.route('/api/attributes/',methods=['GET'])
def getProductAttributes():
    if request.method =='GET':
        results = Attributes.query.limit(10).offset(0).all()
        json_results = []
        for result in results:
            d = {
                'product_id':result.product_id,
                'attribute_id':result.attribute_id,
                'language_id':result.language_id,
                'text':result.text
            }
            json_results.append(d)

        return jsonify(items = json_results)

@app.route('/api/attributes/', methods=['POST'])

def postProductAttributes():
    product_id = request.json['product_id']
    attribute_id = request.json['attribute_id']
    language_id = request.json['language_id']
    text = request.json['text']
    if product_id is None or attribute_id is None or language_id is None or text is None:
        return jsonify({"message": "Error."}), 400
    new_attrib = (product_id,attribute_id,language_id,text)
    db.session.add(new_attrib)
    db.session.commit()
    return jsonify({'message' :'Attribute Created successfully'}), 200

if __name__ == '__main__':
    app.run(debug=True)

When I POST I keep I getting an Internal Server Error. 发布时,我一直收到内部服务器错误。 Any help is highly appreciated. 非常感谢您的帮助。

The traceback is: 追溯为:

seroney-pc - - [23/Dec/2014 20:48:40] "POST /api/attributes HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1453, in dispatch_request
    self.raise_routing_exception(req)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1439, in raise_routing_exception
    raise FormDataRoutingRedirect(request)

Note: this exception is only raised in debug mode 注意:仅在调试模式下引发此异常

You are posting to the URL without a / at the end, but you specified your route with a trailing / . 您要发布到URL的末尾没有 / ,但是您在路由后加上 / When you do that, Flask issues a redirect to the 'canonical' URL, with the / . 当你这样做,瓶发出重定向到“规范”的网址,用/

Because you are using POST, the post data will be lost, so in debug mode an exception is raised instead to inform you that you should use the trailing slash in your post instead. 由于您使用的是POST,因此后的数据将丢失,因此在调试模式下会引发异常,以通知您应在帖子中使用斜杠。

Had you looked at the body of the error message, you'd have seen something like: 假如你看着错误消息的身体 ,你会看到这样的:

FormDataRoutingRedirect: A request was sent to this URL (http://seroney-pc:5000/api/attributes) but a redirect was issued automatically by the routing system to "http://seroney-pc:5000/api/attributes/". FormDataRoutingRedirect:请求已发送到该URL(http:// seroney-pc:5000 / api / attributes),但是路由系统自动将重定向发送到“ http:// seroney-pc:5000 / api / attributes / ”。 The URL was defined with a trailing slash so Flask will automatically redirect to the URL with the trailing slash if it was accessed without one. 该URL定义了一个斜杠,因此如果没有访问Flask,它将自动重定向到带有斜杠的URL。 Make sure to directly send your POST-request to this URL since we can't make browsers or HTTP clients redirect with form data reliably or without user interaction. 请确保直接将您的POST请求发送到此URL,因为我们无法使浏览器或HTTP客户端可靠地重定向表单数据或没有用户交互。

Note: this exception is only raised in debug mode 注意:仅在调试模式下引发此异常

See the Rule Format documentation : 请参阅规则格式文档

URL rules that end with a slash are branch URLs, others are leaves. 以斜杠结尾的URL规则是分支URL,其他则是叶子。 If you have strict_slashes enabled (which is the default), all branch URLs that are visited without a trailing slash will trigger a redirect to the same URL with that slash appended. 如果启用了strict_slashes (默认设置),则所有访问的没有尾随斜杠的分支URL都将触发重定向到添加了该斜杠的相同URL。

Note that your curl POST uses the wrong header; 请注意,您的curl POST使用了错误的标题; you need to set the Content-Type header. 您需要设置Content-Type标头。 Your view is looking for the language_id key, but your post contains only a language key, you need to correct that too: 您的视图正在寻找language_id键,但是您的帖子仅包含一个language键,您也需要更正该错误:

curl -i -H "Content-Type: application/json" -X POST \
     -d '{"attribute_id": "1", "product_id": "44","text":"Something","language_id":"1"}' http://seroney-pc:5000/api/attributes/

The Accept header may be useful too, but it is used for negotiating the response content type, and you have your views hardcoded to return JSON. Accept标头也可能有用,但是它用于协商响应内容类型,并且您已将视图硬编码为返回JSON。

Your code creating the database object is also incorrect, you need to call the model and pass in the arguments as separate arguments, then pass in the resulting to session.add() : 您创建数据库对象的代码也不正确,您需要调用模型并将参数作为单独的参数传递,然后将结果传递给session.add()

new_attrib = Attributes(*new_attrib)
db.session.add(new_attrib)

but just reusing the JSON object would be easier here: 但是在这里重用JSON对象会更容易:

db.session.add(Attributes(**request.json))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM