[Open WebUI] users.py의 5개 업데이트 메서드에서 중복 SELECT 쿼리 제거
PR 링크: open-webui/open-webui#21011 상태: Merged | 변경: +27 / -21
들어가며
Open WebUI의 users.py에는 사용자 정보를 업데이트하는 5개의 메서드가 있다: update_user_role_by_id, update_user_status_by_id, update_user_profile_image_url_by_id, update_last_active_by_id, update_user_by_id. 이 메서드들 모두 동일한 비효율 패턴을 가지고 있었다. db.query(User).filter_by(id=id).update(...) 후에 다시 db.query(User).filter_by(id=id).first()로 같은 레코드를 조회하는 것이다.
핵심 코드 분석
Before: UPDATE + 별도 SELECT
def update_user_role_by_id(self, id, role, db=None):
try:
with get_db_context(db) as db:
db.query(User).filter_by(id=id).update({"role": role})
db.commit()
user = db.query(User).filter_by(id=id).first() # 불필요한 재조회
return UserModel.model_validate(user)
except Exception:
return None
After: fetch-modify-refresh 패턴
def update_user_role_by_id(self, id, role, db=None):
try:
with get_db_context(db) as db:
user = db.query(User).filter_by(id=id).first()
if not user:
return None
user.role = role
db.commit()
db.refresh(user)
return UserModel.model_validate(user)
except Exception:
return None
왜 이게 좋은가
- 쿼리 수 절반 감소: 5개 메서드 모두 UPDATE + SELECT에서 SELECT + commit + refresh로 변경되어, 총 쿼리 수가 2에서 1로 줄어든다.
db.refresh()는 같은 세션 내에서 객체 상태를 갱신한다. - 존재 확인 추가: 기존 코드는 UPDATE가 0행에 영향을 줘도 에러 없이
None을 반환하는first()결과에 의존했다. 새 코드는 명시적으로if not user: return None으로 존재하지 않는 사용자를 조기에 처리한다. - ORM 방식 일관성:
setattr를 사용한 동적 필드 업데이트는model_dump(exclude_none=True)과 자연스럽게 결합되어, 향후 필드 추가 시에도 코드 변경이 최소화된다.
5개 메서드를 동일한 패턴으로 통일한 것도 유지보수 측면에서 좋은 접근이다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [uvloop] uvloop 성능 최적화: Python C API를 활용한 Context 진입/탈출 개선
- 현재글 : [Open WebUI] users.py의 5개 업데이트 메서드에서 중복 SELECT 쿼리 제거
- 다음글 [pytest] 캐시 디렉터리 생성 로직 단순화 — 원자적 생성 함수 추출
댓글