在添加Flask,SQLAlchemy之前检查表中的行中的值是不是已经存在

Posted

技术标签:

【中文标题】在添加Flask,SQLAlchemy之前检查表中的行中的值是不是已经存在【英文标题】:Checking if values in row in table already exists before adding in Flask, SQLAlchemy在添加Flask,SQLAlchemy之前检查表中的行中的值是否已经存在 【发布时间】:2022-01-24 05:19:04 【问题描述】:

我有一个 UserService 连接表,如下所示:

[
    
        "id": 1,
        "service_id": 1,
        "user_id": 1
    ,
    
        "id": 2,
        "service_id": 2,
        "user_id": 1
    ,
    
        "id": 3,
        "service_id": 2,
        "user_id": 2
    ,
    
        "id": 4,
        "service_id": 3,
        "user_id": 1
    ,
    
        "id": 5,
        "service_id": 3,
        "user_id": 2
    
]

在创建新的 UserService 时,如果值已经存在,我不希望用户能够添加条目。我当前的 if 语句当前正在返回 else 语句。我在这里做错了什么?

@bp.route('/user/<userid>/add-service/<serviceid>', methods=['POST'])
def add_service_to_user(userid, serviceid):

    user = db_session.query(User).filter(User.id == userid).first()
    service = db_session.query(Service).filter(Service.id == serviceid).first()

    all_user_services = db_session.query(UserService).all()

    for service in all_user_services:
        if serviceid == service.service_id and userid == service.user_id:
            return jsonify('Message': f'User with id: userid already has Service with id: serviceid')
    else:
        return 'hello'

【问题讨论】:

如果您需要对 service_id user_id 是唯一的,则使用唯一约束强制执行此操作并处理尝试添加具有相同的第二个条目的错误价值观。查询+检查总是会受到TOCTOU的影响,您最终可能会得到多个条目。 【参考方案1】:

您可以在数据库端执行此操作,只需在 .filter()

中使用 and 运算符
.query(Service).filter(Service.id == serviceid && Service.user_id == userid).first()

您可能还想为serviceiduserid 参数定义类型,因为它们是整数。 代码可能看起来像

@bp.route('/user/<int:userid>/add-service/<int:serviceid>', methods=['POST'])
def add_service_to_user(userid, serviceid):

    service = db_session.query(Service).filter(Service.id == serviceid && Service.user_id == userid).first()

    if service is not None:
        return jsonify('Message': f'User with id: userid already has Service with id: serviceid')
    else:
        return 'hello'

    

【讨论】:

以上是关于在添加Flask,SQLAlchemy之前检查表中的行中的值是不是已经存在的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 SQLAlchemy、flask、python 中的唯一数据

Flask SQLAlchemy 多对多插入重复条目

Flask-Sqlalchemy:数据库查询不返回新数据

Flask-SQLAlchemy:在回滚无效事务之前无法重新连接

Flask中对MySQL的基本操作

Flask 学习-13.Flask-SQLAlchemy 新建模型和字段