2016-09-22 6 views
0

SQLAlchemy(1.1.0b3)とPostgresでFlaskアプリケーションを実行しています。SQLAlchemyで一時的にインクリメントを無効にする

Flaskでは、クライアントがタイプデータベースのすべてのインスタンスを取得し、Flaskアプリケーションのクリーンバージョンでそれらをローカルバックアップの方法で再度POSTすることができるAPIを提供します。クライアントがそれらを再び投稿するとき、彼らは彼らがそれらをダウンロードしたときと同じIDを再度持つべきです。

通常の操作でプライマリキーの「インクリメント」オプションを無効にしたくないのですが、クライアントがID付きのPOSTを提供していて、新しいリソースにIDを渡したい場合は、 SQLAlchemy。どのようにして現在のIDの最大値にアクセス/リセットできますか?

@app.route('/objects', methods = ['POST']) 
def post_object(): 

    if 'id' in request.json and MyObject.query.get(request.json['id']) is None: #1 
     object = MyObject() 
     object.id = request.json['id'] 
    else: #2 
     object = MyObject() 

    object.fillFromJson(request.json) 
    db.session.add(object) 
    db.session.commit() 
    return jsonify(object.toDict()),201 

ID #1を持つオブジェクトの束を追加し、IDなしまたは使用されるID #2での追加しようと、私が取得します。

duplicate key value violates unique constraint "object_pkey" 
DETAIL: Key (id)=(2) already exists. 

通常、idがincrementallyを生成しているが、そのIDが既に使用されている場合、そのための検査は行われません。自動インクリメントとINSERTをどうやって得ることができますか?

+1

あなたはどんな問題を抱えていますか? Postgresでは、挿入中に主キー値を設定することができます。 – dirn

+0

'session.add(object)'のように見えますが、 'object'がidを持たない場合、' session.add(object) 'がidなしで最後に呼び出されたときよりも大きなオブジェクトにidを与えます。 –

+0

しかし、あなたが使用したいIDを持っているなら、それをセッションに追加する前にオブジェクトに割り当てるのはなぜですか? – dirn

答えて

0

IDを固定したオブジェクトを追加した後、通常のインクリメンタルビヘイビアが将来の挿入で衝突を起こさないようにする必要があります。

考えられる解決策は、次の挿入IDをテーブル内の最大ID(+1)に設定することです。テーブルに挿入された(固定IDなし)次のオブジェクトがテーブルで検出された最大のIDからIDの増分を継続していきます

@app.route('/objects', methods = ['POST']) 
def post_object(): 
    fixed_id = False 
    if 'id' in request.json and MyObject.query.get(request.json['id']) is None: #1 
     object = MyObject() 
     object.id = request.json['id'] 
     fixed_id = True 
    else: #2 
     object = MyObject() 

    object.fillFromJson(request.json) 
    db.session.add(object) 
    db.session.commit() 

    if fixed_id: 
     table_name = MyObject.__table__.name 
     db.engine.execute("SELECT pg_catalog.setval(pg_get_serial_sequence('%s', 'id'), MAX(id)) FROM %s;" % (table_name, table_name)) 

    return jsonify(object.toDict()),201 

:あなたはあなたのコードに、次の追加機能を備えたことを行うことができます。

関連する問題