일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ansible
- asyncio
- github
- Service
- ebs
- Python
- YAML
- elasticsearch
- asgi
- leetcode
- Kubernetes
- IAC
- event loop
- Django
- intervals
- K8S
- docker
- EKS
- WSGI
- AWS
- EC2
- FastAPI
- IAM
- 자바스크립트
- 쿠버네티스
- dockerfile
- Deployment
- terraform
- DevOps
- POD
- Today
- Total
궁금한게 많은 개발자 노트
SQLalchemy 본문
SQLalchemy를 알아보기 전에 ORM의 개념에 대해 먼저 알아보려합니다.
ORM(Object Relational Manager)은 객체-관계 mapping을 의미합니다. 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 type 시스템 간에 데이터를 변환하기 위한 프로그래밍 기술입니다.
- 메모리에서의 클래스(객체 지향 프로그래밍)와 관계형 데이터베이스의 테이블은 서로 일치하지 않으므로 ORM을 통해 불일치를 해결합니다.
간단하게 요약하면, 애플리케이션을 만드려면 데이터가 필요합니다. 데이터는 데이터베이스에서 관리하고 있으므로, 데이터베이스에서 쿼리로 원하는 데이터를 가져오려면 원래 SQL Tool 사용이 필요했지만, 지금은 애플리케이션 안에서 sql의 동작을 대신해주는 ORM기능이 있다고 생각하면 됩니다.
ORM을 통해 실제로 쿼리를 실행할 필요없이 프로그래밍 방식으로 안전하고 편리하게 애플리케이션 안에서 데이터베이스에 연결할 수 있습니다. 이 ORM 중 하나로 SQLAlchemy가 있다.
SQLalchemy란?
SQLalchemy란 python에서 사용할 수 있는 ORM중 하나입니다. 다른 ORM 라이브러리와 다른 점 중 하나로는 자체적으로 스키마를 생성하지 않는다는 것입니다. 그렇기 때문에 애플리케이션 코드나 데이터베이스 시스템에 간섭하지 않는 다는 특징이 있습니다.
또 다른 참고할만한 정의로는,
파이썬 SQL 툴킷(toolkit)으로써, Object Relational Mapper(ORM)역할을 한다. 개발자로 하여금 에러에 민감하지 않으면서, 부드러운 데이터베이스 트랜젝션 동작이 가능한 앱을 만들 수 있게한다. ORM은 파이썬 클래스를 관계형 데이터베이스의 테이블로 해석하고, 파이썬형태의 SQL Alchemy 표현언어를 SQL로 변환해준다. 이 기능은 개발자가 파이썬 syntax안에서 SQL 쿼리를 작성할 수 있도록 해준다. SQLAlchemy는 또한, 데이터베이스의 연결을 추상화해주며, 자동으로 연결에 대한 유지 및 보수 기능까지 제공한다.
SQLalchemy의 장점
* 모델과 데이터베이스를 한번만 정의
데이터베이스 파일과 모델 파일을 분리함으로써, 데이터베이스와 모델을 한번에 정의할 수 있으며, 필요할 때마다 불러올 수 있습니다.
* asyncio를 지원하는 것 또한 장점
SQLalchemy 사용법
1. connection 생성 (mapping 선언)
from sqlalchemy.orm import declarative_base
Base = declarative_base()
2. session 생성 및 engine과 연결
from sqlalchemy import create_engine
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
// engine생성
engine = create_async_engine(f"postgresql+asyncpg://{self.db_user}:{self.db_password}@{self.db_host}/{self.db_name}")
// session생성 및 연결
async_session = sessionmaker(
autocommit=False,
autoflush=False,
expire_on_commit=False,
bind=engine,
class_=AsyncSession,
)
context class를 사용하면 session의 관리를 더 수월하게 할 수 있다.
__enter__ : with문이 시작될 때 실행되고 return하는 값이 변수에 들어간다.
__exit__ : with문 종료 시 실행된다.
class SessionContext:
session = None
def __enter__(self):
self.session = Session()
return self.session
def __exit__(self):
self.session.close()
with SessionContext() as session:
# DB 작업 작성
3. 생성할 모델 만들기
- 생선한 Base를 기반으로 모델을 생성하고, __tablename__을 필수적으로 선언해야합니다.
class DBUser(Base):
__tablename__ = 'users' # 필수적으로 선언 -> table의 이름
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
email = Column(String, nullable=False)
password = Column(String, nullable=False)
inactivate = Column(Boolean, default=False)
- relationship생성 : relationship이 작성된 다른 쪾을 참조합니다.
from sqlalchemy.orm import relationship
#relation을 사용할 model 내부에
relationship(연결할 model, [options,,,,,])
#options
#ex. back_populate : relation에서 연결된 부분에서 접근할시의 이름
#order by : model명.id -> id순으로 정렬
4. Schema생성
- 데이터베이스를 초기 생성할 때에는 create_all을 사용해서 생성합니다.
- 최초 한 번만 create_all을 사용합니다.
- 이미 존재하는 db에 연결할 때에는 bind를 사용합니다.
Base.metadata.create_all(engine) #1.에서 만든 base와 2.에서 만든 engine을 사용
Base.metadata.bind = engine
5. CRUD사용
# CRUD
# CREATE: table에 정보 넣기
def create():
ed_user = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
session.add(ed_user) #값 add하고
#commit을 하면 data가 table에 삽입됨
session.commit()
def create_all():
session.add_all([User(....), User(....), ......]) #한 번에 여러값을 삽입
# READ: table에 있는 정보 불러오기
def get():
user1.session.query(User).first() #User table의 첫번째 값을 불러옴
#filter를 사용해 원하는 값을 불러올 수 있음
session.query(User).filter(User.name.in_(['Edwardo', 'fakeuser'])).all()
def get_all():
session.query(User, User.name).all() #User 객체와 User 중 이름만을 select함
# UPDATE: table에 있는 정보 갱신하기
def update(item_id):
# 해당하는 아이템 찾아오기
item = session.query(User).filter(User.id==item_id).first()
# 값 변경 진행
# DB에 갱신 값 저장
session.add(item)
session.commit()
# DELETE: table에 있는 정보 삭제하기
def delete(item_id):
session.query(User).filter(User.id==item_id).delete()
session.commit
# filter_by vs. filter
# 두 함수 모두 원하는 정보를 filtering 하기 위해 사용한다.
# filter_by : 결과물 filtering
# filter : filter_by보다 좀 더 유연한 SQL 표현을 사용할 수 있다.
# -> filter 연산자를 사용할 수 있다.
# equals : ==
# not equals : !=
# like : User.name.like('%ed%')
# match : User.name.match('wendy')
https://docs.sqlalchemy.org/en/14/
'Back End' 카테고리의 다른 글
[ FastAPI ] Middleware에서 request body 사용 불가 (2) | 2022.10.05 |
---|---|
[ Python ] FastAPI - Depends (0) | 2022.06.03 |
[ Python ] pydantic (0) | 2022.05.24 |
[ Python ] 병렬 처리 concurrent future (4) | 2022.05.23 |
Fast API (0) | 2022.05.23 |