Вы можете сделать одну из двух вещей:
Сделать запрос для пользователей с этим полем:
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, независимо от того, поймали ли вы ошибку или нет, сеанс, в котором вы работали, становится недействительным. Чтобы продолжить использовать сессию, вам нужно ввести db.session.rollback()
.
Последнее лучше, потому что на не распространяются условия гонки . Представьте, что два пользователя пытаются зарегистрировать один и тот же адрес банка одновременно:
- Пользователь A отправляет,
User.query.filter().first()
возвращает None
, потому что никто еще не использует адрес.
- Почти одновременно, пользователь B отправляет,
User.query.filter().first()
возвращает None
, потому что никто еще не использует адрес.
- Адрес банка пользователя А записывается в базу данных, успешно
- Банковский адрес пользователя B не может быть записан в базу данных, потому что проверка целостности не удалась, так как пользователь A только что записал этот адрес.
Так что просто перехватывает исключение , потому что транзакции базы данных гарантируют, что база данных 1043 * заблокирует таблицу перед проверкой ограничения и добавлением или обновлением пользователя.
Вы также можете заблокировать всю таблицу во Flask, но Python общается с базой данных намного медленнее. Если у вас загруженный сайт, вы не хотите, чтобы обновление базы данных происходило медленно, в результате многие пользователи ожидают снятия блокировки. Вы хотите, чтобы блокировка была минимальной и как можно более короткой, и чем ближе к фактическим данным, которые вы блокируете, тем раньше вы сможете снова снять блокировку. Базы данных очень хороши в такого рода блокировках и очень близки к своим данным (естественно), поэтому оставьте блокировку для базы данных и используйте вместо этого исключение.