SQLAlchemy - 관계 속성 기준 필터링
예시
다음은 User
모델과 Address
모델을 정의하는 예시입니다.
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255))
addresses = relationship("Address", back_populates="user")
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
street = Column(String(255))
city = Column(String(255))
state = Column(String(255))
country = Column(String(255))
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User", back_populates="addresses")
이 예시에서 User
모델은 addresses
라는 관계 속성을 가지고 있습니다. 이 속성은 Address
모델의 인스턴스 목록을 참조합니다. Address
모델은 또한 user
라는 관계 속성을 가지고 있으며 이 속성은 User
모델의 인스턴스를 참조합니다.
관계 속성 기준 필터링
다음은 관계 속성을 기준으로 데이터를 검색하는 방법의 몇 가지 예시입니다.
특정 속성 값을 기준으로 필터링
다음 코드는 city
속성이 "서울"인 모든 주소를 검색합니다.
addresses = session.query(Address).filter(Address.city == "서울").all()
관계 속성에서 값을 사용하여 필터링
addresses = session.query(Address).filter(Address.user.name == "홍길동").all()
IN 연산자 사용
cities = ["서울", "부산"]
addresses = session.query(Address).filter(Address.city.in_(cities)).all()
addresses = session.query(Address).filter(Address.city.like("서울%")).all()
하위 쿼리 사용
다음 코드는 name
속성이 "홍길동"인 사용자의 모든 주소를 검색하고, 그 주소 중 city
속성이 "서울"인 주소만 선택합니다.
user = session.query(User).filter(User.name == "홍길동").one()
addresses = session.query(Address).filter(Address.user == user).filter(Address.city == "서울").all()
결론
SQLAlchemy - 관계 속성 기준 필터링 예제 코드
예시
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255))
addresses = relationship("Address", back_populates="user")
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
street = Column(String(255))
city = Column(String(255))
state = Column(String(255))
country = Column(String(255))
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User", back_populates="addresses")
관계 속성 기준 필터링 예제
addresses = session.query(Address).filter(Address.city == "서울").all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
user = session.query(User).filter(User.name == "홍길동").one()
addresses = session.query(Address).filter(Address.user == user).all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=2, street='부산광안리 1', city='부산', state='부산광역시', country='대한민국', user_id=1)]
cities = ["서울", "부산"]
addresses = session.query(Address).filter(Address.city.in_(cities)).all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=2, street='부산광안리 1', city='부산', state='부산광역시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
addresses = session.query(Address).filter(Address.city.like("서울%")).all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
user = session.query(User).filter(User.name == "홍길동").one()
addresses = session.query(Address).filter(Address.user == user).filter(Address.city == "
SQLAlchemy - 관계 속성 기준 필터링 대체 방법
하위 쿼리 대신 JOIN 사용
하위 쿼리 대신 JOIN
을 사용하면 두 테이블을 직접 연결하여 데이터를 검색할 수 있습니다. 이 방법은 하위 쿼리보다 더 효율적일 수 있으며, 특히 두 테이블 사이에 많은 관계가 있는 경우 유용합니다.
addresses = session.query(Address).join(User).filter(User.name == "홍길동").filter(Address.city == "서울").all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
subquery 함수 사용
subquery
함수를 사용하면 하위 쿼리를 더 간결하게 작성할 수 있습니다.
user_id = session.query(User).filter(User.name == "홍길동").one().id
addresses = session.query(Address).filter(Address.user_id == user_id).filter(Address.city == "서울").all()
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
any() 및 all() 함수 사용
any()
및 all()
함수를 사용하면 관계 속성에 대한 조건을 더 유연하게 설정할 수 있습니다.
users = session.query(User).filter(User.addresses.any(city="서울"))
print(users) # [User(id=1, name='홍길동', email='[email protected]'), User(id=3, name='김철수', email='[email protected]')]
addresses = session.query(Address).filter(Address.user.addresses.all(city="서울"))
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
exists() 함수 사용
users = session.query(User).filter(session.query(Address).filter(Address.user_id == User.id).filter(Address.city == "서울").exists())
print(users) # [User(id=1, name='홍길동', email='[email protected]'), User(id=3, name='김철수', email='[email protected]')]
addresses = session.query(Address).filter(session.query(Address).filter(Address.city == "서울").filter(Address.user == Address.user).exists())
print(addresses) # [Address(id=1, street='서울역로 1', city='서울', state='서울특별시', country='대한민국', user_id=1), Address(id=5, street='종로 1', city='서울', state='서울특별시', country='대한민국', user_id=3)]
in_ 연산자 대신 contains() 함수 사용
users = session.query(User).filter(User.addresses.contains(Address(city="서울")))
print(users) # [User(id=1, name='홍길동', email='[email protected]'), User(id=3, name='김철수', email='
python filter sqlalchemy