코드로 우주평화

Sqlalchemy 의 scalar 메서드들을 살펴보자 본문

나는 이렇게 학습한다/DB

Sqlalchemy 의 scalar 메서드들을 살펴보자

daco2020 2024. 1. 24. 19:14

 

Scalar 메서드는 쿼리를 통해 가져온 결과를, 단일 데이터 요소(ex. ORM)로 반환하는 데 사용하는 sqlalchemy.engine.Result 클래스의 메서드입니다. 이번 글에서는 SQLAlchemy에서 제공하는 Scalar 메서드들에 대해 알아보고, 각 메서드들의 적합한 예시를 함께 살펴보겠습니다. 🥸

 

 

 

scalar()

scalar() 메서드는 쿼리 결과의 첫 번째 행의 값을 반환합니다. 만약 결과가 없으면 None을 반환합니다. scalar() 메서드는 주로 결과가 최대 하나만 있을 것으로 예상되거나, 여러 결과 중 첫 번째 값만 필요한 경우에 사용됩니다.

 

예시: 특정 조건을 만족하는 첫 번째 사용자의 이름 조회

first_user_name = session.query(User.name).filter(User.age > 20).scalar()
if first_user_name:
    print(f"조건을 만족하는 첫 번째 사용자의 이름은 {first_user_name}입니다.")
else:
    print("조건을 만족하는 사용자가 없습니다.")

 

이 예시에서는 20세 이상인 사용자 중 첫 번째 사용자 이름을 조회합니다. 결과가 여러 개 있더라도, scalar() 메서드는 첫 번째 사용자의 이름만 반환합니다. 만약 해당 조건을 만족하는 사용자가 없다면, None을 반환하게 되죠.

 

위 예시 처럼 scalar() 메서드는 결과가 하나 또는 없을 때 유용하게 사용됩니다. 결과가 여러 개 있을 경우에도 첫 번째 결과만을 반환하기 때문에, 결과가 정확히 하나여야 하는 상황에서는 scalar_one() 또는 scalar_one_or_none() 메서드가 더 적합합니다.

 

 

 

scalar_one()

scalar_one() 메서드는 쿼리 결과가 정확히 하나일 때 그 값을 반환합니다. 결과가 없거나, 하나 이상이라면 예외를 발생시킵니다.

 

예시: 유니크한 사용자 ID로 사용자의 이름을 조회

name = session.query(User.name).filter(User.id == user_id).scalar_one()
print(f"사용자의 이름은 {name}입니다.")

 

만약 결과가 값을 반환하지 않으면 NoResultFound 예외를, 여러 값을 반환하면 MultipleResultsFound 예외를 발생시킵니다.

 

 

 

scalar_one_or_none()

scalar_one_or_none() 메서드는 결과가 정확히 하나이거나 없을 때 사용합니다. 결과가 하나일 때는 그 값을 반환하고, 없으면 None 을 반환합니다. 만약 결과가 하나 이상이라면 예외를 발생시킵니다.

 

예시: 유니크한 상품 ID로 상품의 가격을 조회

product_price = session.query(Product.price).filter(Product.id == product_id).scalar_one_or_none()
if product_price is not None:
    print(f"제품 가격은 {product_price}원입니다.")
else:
    print("해당 제품이 존재하지 않습니다.")

 

만약 결과가 여러 값을 반환하면 MultipleResultsFound 에외를 발생시킵니다.

 

 

 

scalars()

scalars() 메서드는 쿼리 결과의 값들을 반환합니다. 이 메서드는 ScalarResult 객체를 반환하는데, 해당 객체를 순회하거나 all() 과 같은 메서드를 다시 호출해야 값을 가져올 수 있습니다.

 

예시: 특정 조건을 만족하는 여러 사용자의 ID를 조회

user_ids = session.query(User.id).filter(User.is_active == True).scalars().all()
print(f"활성 사용자 ID 리스트: {user_ids}") # 활성 사용자 ID 리스트: [1, 3]

 

scalars() 를 통해 반환된 ScalarResult 객체는 unique(), partitions(), fetchmany() 등의 메서드를 호출하여 원하는 값들만 가져올 수도 있습니다. 

 

 

scalars().unique() 는 중복되는 객체들을 제거하여 고유한 객체들만 반환합니다. 보통 join 과정에서 중복되는 row 가 생성되면 이 unique() 를 통해 해결할 수 있습니다.  The unique() method must be ... 에러 해결방법

result = session.execute(stmt).scalars().unique()

 

scalars().partitions(size) 는 size 크기 만큼의 순회하는 서브리스트를 반환합니다.

for partition in session.execute(stmt).scalars().partitions(size=10):
    for obj in partition:
        print(obj)

 

scalars().fetchall() 은 모든 값을 반환합니다.

results = session.execute(stmt).scalars().fetchall()

 

scalars().fetchmany(size=10) 는 지정된 수 만큼의 값을 반환합니다.

results = session.execute(stmt).scalars().fetchmany(size=10)

 

scalars().all() 은 fetchall() 와 동일하게 모든 값을 리스트로 반환합니다.

results = session.execute(stmt).scalars().all()

 

scalars().first() 는 첫 번째 값을 반환합니다. 만약 값이 없다면 None 을 반환합니다.

result = session.execute(stmt).scalars().first()

 

scalars().one_or_none() 은 하나의 값을 반환합니다. 만약 값이 많다면 예외를 발생시킵니다.

result = session.execute(stmt).scalars().one_or_none()

 

scalars().one() 은 하나의 값을 반환합니다. 만약 값이 없거나 많다면 예외를 발생시킵니다.

result = session.execute(stmt).scalars().one()

 

 


 

 

마무리

'Scalar'는 라틴어 'scala'에서 유래했으며, 이는 '계단'이나 '저울'을 의미합니다. 수학과 물리학에서 '스칼라'는 크기만을 가지고 방향성이 없는 물리량을 뜻하는데요. 프로그래밍에서는 이 개념이 확장되어 단일 값을 나타내는 변수나 데이터를 의미한다고 합니다.

 

개발 과정에서 DB 데이터를 가져올 때 Scalar 메서드를 자주 사용하는데요. 종종 헷갈릴 때가 있어 이번에 간단히 정리해 보았습니다. 정리하는 과정에서 단어의 뜻과 어원도 배울 수 있었네요. 😚

 

 

레퍼런스

 

Working with Engines and Connections — SQLAlchemy 2.0 Documentation

The caching feature requires that the dialect’s compiler produces SQL strings that are safe to reuse for many statement invocations, given a particular cache key that is keyed to that SQL string. This means that any literal values in a statement, such as

docs.sqlalchemy.org