暂时禁用SQLAlchemy中的增量

时间:2016-09-22 13:12:34

标签: python rest flask sqlalchemy auto-increment

我正在使用SQLAlchemy(1.1.0b3)和Postgres运行Flask应用程序。

使用Flask,我提供了一个API,通过该API,客户端可以获取类型数据库的所有实例,并在Flask应用程序的干净版本上再次发布它们,作为本地备份的一种方式。当客户再次发布它们时,它们应该再次具有与下载时相同的ID。

我不想禁用"增量"用于正常操作的主键的选项但是如果客户端提供带有POST的ID并且希望给出新资源所述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

当添加一堆标识为#1的对象,然后尝试添加WITHOUT id或使用的标识#2时,我得到了。

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

通常,id会生成incrementally但是当已经使用了该ID时,就不会检查它。如何在自动增量和INSERT之间进行操作?

1 个答案:

答案 0 :(得分:0)

添加具有固定ID的对象后,您必须确保正常的增量行为不会导致与将来插入的任何冲突。

我能想到的一个可能的解决方案是将下一个插入ID设置为表中找到的最大ID(+1)。您可以通过以下代码添加来实现:

@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

插入表中的下一个对象(没有固定的id)将继续从表中找到的最大ID开始增加id。