0

次の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"
}

私のコードは次のとおりです。

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)

注: この例外はデバッグ モードでのみ発生します

4

1 に答える 1

4

末尾に を付けずにURL に投稿していますが、末尾/に を付けてルート/指定しています。これを行うと、Flask は「正規の」URL へのリダイレクトを発行します/

POST を使用しているため、投稿データが失われるため、デバッグ モードでは代わりに例外が発生し、代わりに投稿で末尾のスラッシュを使用する必要があることが通知されます。

エラー メッセージの本文を見ると、次のようになっているはずです。

FormDataRoutingRedirect: この URL (http://seroney-pc:5000/api/attributes) に要求が送信されましたが、ルーティング システムによって自動的に「http://seroney-pc:5000/api/attributes/」へのリダイレクトが発行されました。 "。URL は末尾のスラッシュで定義されているため、Flask は、末尾のスラッシュなしでアクセスされた場合、末尾のスラッシュのある URL に自動的にリダイレクトします。POST リクエストをこの URL に直接送信するようにしてください。ブラウザや HTTP クライアントをフォーム データで確実にリダイレクトしたり、ユーザーの操作なしにリダイレクトしたりすることはできません。

注: この例外はデバッグ モードでのみ発生します

ルール形式のドキュメントを参照してください:

スラッシュで終わる URL ルールはブランチ URL で、それ以外はリーフです。strict_slashesを有効にしている場合(デフォルト)、末尾のスラッシュなしで訪問されたすべてのブランチ URL は、そのスラッシュが追加された同じ URL へのリダイレクトをトリガーします。

curlPOST が間違ったヘッダーを使用していることに注意してください。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))
于 2014-12-23T18:30:13.703 に答える