Changes for sqlalchemy 2.0

This commit is contained in:
Aditi Anand
2024-04-24 16:27:20 -04:00
parent df2a590f1a
commit ad55eef5e9
14 changed files with 160 additions and 166 deletions

View File

@@ -2,6 +2,8 @@ import uuid
from datetime import datetime, timedelta
from secrets import randbelow
import sqlalchemy
from flask import current_app
from sqlalchemy import func
from sqlalchemy.orm import joinedload
@@ -11,7 +13,7 @@ from app.dao.permissions_dao import permission_dao
from app.dao.service_user_dao import dao_get_service_users_by_user_id
from app.enums import AuthType, PermissionType
from app.errors import InvalidRequest
from app.models import User, VerifyCode
from app.models import Organization, Service, User, VerifyCode
from app.utils import escape_special_characters, get_archived_db_column_value
@@ -39,10 +41,21 @@ def get_login_gov_user(login_uuid, email_address):
user = User.query.filter_by(login_uuid=login_uuid).first()
if user:
if user.email_address != email_address:
save_user_attribute(user, {"email_address": email_address})
try:
save_user_attribute(user, {"email_address": email_address})
except sqlalchemy.exc.IntegrityError as ie:
# We are trying to change the email address as a courtesy,
# based on the assumption that the user has somehow changed their
# address in login.gov.
# But if we cannot change the email address, at least we don't
# want to fail here, otherwise the user will be locked out.
current_app.logger.error(ie)
db.session.rollback()
return user
# Remove this 1 July 2025, all users should have login.gov uuids by now
user = User.query.filter_by(email_address=email_address).first()
user = User.query.filter(User.email_address.ilike(email_address)).first()
if user:
save_user_attribute(user, {"login_uuid": login_uuid})
return user
@@ -172,15 +185,14 @@ def update_user_password(user, password):
def get_user_and_accounts(user_id):
# TODO: With sqlalchemy 2.0 change as below because of the breaking change
# at User.organizations.services, we need to verify that the below subqueryload
# that we have put is functionally doing the same thing as before
return (
User.query.filter(User.id == user_id)
.options(
# eagerly load the user's services and organizations, and also the service's org and vice versa
# (so we can see if the user knows about it)
joinedload(User.services),
joinedload(User.organizations),
joinedload(User.organizations.services),
joinedload(User.services.organization),
joinedload(User.services).joinedload(Service.organization),
joinedload(User.organizations).subqueryload(Organization.services),
)
.one()
)