如何在Flask-SQLAlchemy中获取已提交数据并建立表关联?
解决方案
首先纠正模型关联的逻辑错误:
你当前的address表定义了img_id外键依赖img_details.id,这意味着必须先创建img_details才能创建address,和你“先提交address再关联img_details”的需求完全相反。需要调整外键到img_details表,让它关联address.id。
1. 修正模型定义
class address(db.Model): id = db.Column(db.Integer, primary_key=True) city = db.Column(db.String(45), unique=False) state = db.Column(db.String(45), unique=False) zip_code = db.Column(db.String(45), unique=False) # 移除原有的img_id外键,改为关联关系 img_details = db.relationship('img_details', backref='address', lazy='joined') class img_details(db.Model): id = db.Column(db.Integer, primary_key=True) img_url = db.Column(db.String(120), unique=False) description = db.Column(db.String(4000), unique=False) short_description = db.Column(db.String(120), unique=False) # 添加外键关联address.id address_id = db.Column(db.Integer, db.ForeignKey('address.id'), nullable=False)
2. 获取已提交记录的ID
SQLAlchemy在调用db.session.commit()后,模型实例的主键字段(比如id)会自动被数据库填充,直接访问实例的id属性即可拿到刚插入的记录ID,不需要额外方法。
3. 修改视图函数逻辑
调整创建顺序,先创建address并提交,拿到其ID后再创建img_details并关联:
@app.route('/user_data', methods=["POST"]) def user_image(): description_value = request.form['description'] short_description_value = request.form['short_description'] img_url_value = request.form['uploaded_file'] address_zip_code_value = request.form['address_zip_code'] address_city_value = request.form['address_city'] address_state_value = request.form['address_sate'] # 先创建并提交address记录 upload_address_details = address( zip_code=address_zip_code_value, city=address_city_value, state=address_state_value ) db.session.add(upload_address_details) db.session.commit() # 直接访问upload_address_details.id拿到刚插入的ID # 创建img_details时关联address的ID upload_img_data = img_details( img_url=img_url_value, short_description=short_description_value, description=description_value, address_id=upload_address_details.id # 关联刚创建的address的ID ) db.session.add(upload_img_data) db.session.commit() return jsonify({'result': 'submitted', 'address_id': upload_address_details.id, 'img_id': upload_img_data.id})
额外优化:使用事务(可选)
如果希望两个操作要么都成功要么都失败,可以用事务包裹,避免部分提交的情况:
@app.route('/user_data', methods=["POST"]) def user_image(): try: description_value = request.form['description'] short_description_value = request.form['short_description'] img_url_value = request.form['uploaded_file'] address_zip_code_value = request.form['address_zip_code'] address_city_value = request.form['address_city'] address_state_value = request.form['address_sate'] upload_address_details = address( zip_code=address_zip_code_value, city=address_city_value, state=address_state_value ) db.session.add(upload_address_details) # 不需要提前commit,flush即可拿到ID(数据库会生成ID但不提交事务) db.session.flush() upload_img_data = img_details( img_url=img_url_value, short_description=short_description_value, description=description_value, address_id=upload_address_details.id ) db.session.add(upload_img_data) db.session.commit() return jsonify({'result': 'submitted', 'address_id': upload_address_details.id, 'img_id': upload_img_data.id}) except Exception as e: db.session.rollback() return jsonify({'result': 'failed', 'error': str(e)}), 500
用db.session.flush()代替提前commit,既可以拿到生成的ID,又能保证两个操作在同一个事务里,提升数据一致性。
内容的提问来源于stack exchange,提问作者venkat g
相关产品推荐
相关产品推荐

