You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:53:23