gpt4 book ai didi

python - 如何在 SQLAlchemy、Flask、Python 中处理唯一数据

转载 作者:太空宇宙 更新时间:2023-11-03 13:27:56 26 4
gpt4 key购买 nike

您通常如何处理 Flask 中的唯一数据库条目?我的数据库模型中有以下列:

bank_address = db.Column(db.String(42), unique=True)

问题是,甚至在我检查它是否已经在数据库中之前,我得到一个错误:

检查它是否是唯一的,然后写入数据库:

if request.method == 'POST':
if user.bank_address != request.form['bank_address_field']:
user.bank_address = request.form['bank_address_field']
db.session.add(user)
db.session.commit()

我得到的错误:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: user.bank_address_field [SQL: 'UPDATE user SET bank_address_field=? WHERE user.id = ?']

最佳答案

你可以做以下两件事之一:

  • 查询具有该字段的用户:

    if User.query.filter(User.bank_address == request.form['bank_address_field']).first():
    # error, there already is a user using this bank address

    但是,这有一个大问题,请参见下文。

  • 捕获异常:

    from sqlalchemy.exc import IntegrityError

    try:
    db.session.commit()
    except IntegrityError:
    db.session.rollback()
    # error, there already is a user using this bank address or other
    # constraint failed

    IntegrityError 可以从 sqlalchemy.exc 导入。一旦引发 IntegrityError,无论您是否发现错误,您正在使用的 session 都会失效。要继续使用 session ,您需要发出 db.session.rollback()

后者更好,因为它不受竞争条件的限制。想象一下,两个用户同时尝试注册同一个银行地址:

  • 用户 A 提交,User.query.filter().first() 返回 None 因为还没有人使用该地址。
  • 几乎在同一时间,用户 B 提交,User.query.filter().first() 返回 None 因为还没有人使用该地址.
  • 用户A的银行地址写入数据库成功
  • 用户 B 的银行地址无法写入数据库,因为完整性检查失败,因为用户 A 刚刚记录了该地址。

所以只捕获异常,因为数据库事务保证数据库在测试约束和添加或更新用户之前先锁定表。

您也可以在 Flask 中锁定整个表,但 Python 与数据库对话要慢得多。如果您有一个繁忙的站点,您不希望数据库更新缓慢,您最终会遇到很多用户等待锁定被清除的情况。您希望将锁定保持在最低限度,并尽可能短,并且越接近您锁定的实际数据,您可以越早再次释放锁定。数据库非常擅长这种锁定,并且非常接近它们的数据(自然),因此将锁定留给数据库并依赖于异常。

关于python - 如何在 SQLAlchemy、Flask、Python 中处理唯一数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52075642/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com