我正在使用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之间进行操作?
答案 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。