Python Flask SQLalchemy JSON POST Ошибка
Я пытаюсь опубликовать следующий JSON и сохранить в базе данных MySQL на сервере Flask и Python 2.7, беспокойный фреймворк и SQLAlchemy с помощью curl:
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"
}
Мой код выглядит следующим образом:
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)
Когда я POST я продолжаю я получаю Внутреннюю ошибку сервера. Любая помощь высоко ценится.
Следом является:
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)
Примечание: это исключение возникает только в режиме отладки
1 ответ
Вы публикуете на URL без /
в конце, но вы указали свой маршрут с трейлингом /
, Когда вы делаете это, Flask выдает перенаправление на "канонический" URL с /
,
Поскольку вы используете POST, данные поста будут потеряны, поэтому в режиме отладки вместо этого выдается исключение, информирующее вас о том, что вместо этого вы должны использовать косую черту в своем посте.
Если бы вы посмотрели текст сообщения об ошибке, вы бы увидели что-то вроде:
FormDataRoutingRedirect: на этот URL был отправлен запрос (http://seroney-pc:5000/api/attribute), но система маршрутизации автоматически произвела перенаправление на "http://seroney-pc:5000/api/attribute /". URL был определен через косую черту, поэтому Flask автоматически перенаправит на URL с косой чертой, если к нему обращались без такового. Обязательно отправляйте ваш POST-запрос напрямую на этот URL-адрес, поскольку мы не можем заставить браузеры или HTTP-клиенты перенаправлять данные формы надежно или без участия пользователя.
Примечание: это исключение возникает только в режиме отладки
См. Документацию формата правил:
Правила URL, заканчивающиеся косой чертой, являются URL-адресами ветвей, остальные - листьями. Если у вас включен строгий слэш (который используется по умолчанию), все URL-адреса ветвей, которые посещаются без косой черты, будут вызывать перенаправление на тот же URL-адрес с добавленной косой чертой.
Обратите внимание, что ваш curl
POST использует неправильный заголовок; вам нужно установить заголовок Content-Type. Ваш взгляд ищет 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/
Accept
заголовок также может быть полезен, но он используется для согласования типа содержимого ответа, и у вас есть жестко запрограммированные представления для возврата JSON.
Ваш код, создающий объект базы данных, также неверен, вам нужно вызвать модель и передать аргументы как отдельные аргументы, а затем передать полученный результат session.add()
:
new_attrib = Attributes(*new_attrib)
db.session.add(new_attrib)
но простое повторное использование объекта JSON будет проще:
db.session.add(Attributes(**request.json))