[Python] SQLAlchemy
SQLAlchemy๋ ํ์ด์ฌ ํ๊ฒฝ์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ORM ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ๋ฐฉ๋ฒ๊ณผ CRUD ์๋ ๋ฐฉ๋ฒ ์ ๋๋ง ์ ๋ฆฌํด๋ณด๊ฒ ๋ค.
์ค์นํ๊ธฐ
์์ผ๋ฏธ๋ฅผ ์ฐ๋ ค๋ฉด ๋ชจ๋ 2๊ฐ๊ฐ ํ์ํ๋ค.
๊น์์ค๋ค.
pip install sqlalchemy psycopg2


๋์ผ๋ฉด ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ์ก์๋ณด์.
๋๋ ๋ค์๊ณผ ๊ฐ์ด ์์ผ๋ฏธ ๊ด๋ฆฌ์ฉ ์๋ธ๋ชจ๋ "models"๋ฅผ ๋๊ณ , ๊ณตํต์ ์ธ ๊ธฐ๋ฅ์ base์ ๋๊ณ ํ
์ด๋ธ๋ณ๋ก ๋ณ๋์ ์์คํ์ผ์ ๋๋ ํํ๋ฅผ ์ฌ์ฉํ๋ค.

๊ธฐ๋ณธ ์ฐ๊ฒฐ ์ค์
base.py๋ฅผ ๋จผ์ ๋ณด๊ฒ ๋ค.
์ฌ๊ธฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ด๋, ๊ทธ์ ๊ด๋ จ๋ ๊ธฐ๋ณธ์ ์ธ ์์๋ค์ ๋ค ๋ฃ์ด๋จ๋ค.
from sqlalchemy.orm import declarative_base
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import sessionmaker, scoped_session
engine = create_engine("postgresql://postgres:ํจ์ค์๋@localhost:5432/alchemy_test", echo=True)
get_db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
def sync_db():
Base.metadata.create_all(bind=engine)
get_db_session๋ session์ ๊ฐ์ ธ์์ฃผ๋ ํจ์์ธ๋ฐ, DB ์ปค๋ฅ์
๊ฐ๋
์ด๋ผ ์๊ฐํ๋ฉด ๋๋ค.
Base๋ ์ํฐํฐ๋ฅผ ์ ์ํ ๋ ์ฌ์ฉํ ๊ธฐ๋ฐ ํด๋์ค๋ค. ์ด๊ฑธ ์์๋ฐ๋ ๊ฒ์ผ๋ก ์ดํ์ ์ ์ํ ๋ชจ๋ ์ํฐํฐ๊ฐ ํ๋๋ก ์ ์ด๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ
์ด๋ธ ์ด๊ธฐํ์ฉ ํจ์ sync_db๋ ํ๋ ์ ์ํด๋๋ค. ์ ์ํ ์ํฐํฐ๋ฅผ create tableํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
์ฌ๊ธฐ์ ๋ฐ๋ก ํ์ง ์๊ณ ํจ์๋ก๋ง ๋ ๊ฒ์, ์ํฐํฐ๊ฐ ์ ๋ถ import๋ฅผ ํตํด์ load๋ ์์ ์๋ง ์ ํจํ๊ฒ ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ ๊ฑด ์ต์์ ๋ชจ๋์์ ์คํํ๊ฒ ๋ค.
์ํฐํฐ ์ ์
ํ
์ด๋ธ์ ์ด๋ฐ์์ผ๋ก ์ ์ํ๋ฉด ๋๋ค.
Base๋ฅผ ์์๋ฐ๊ณ , __tablename__์ผ๋ก ํ
์ด๋ธ๋ช
์ ์ ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ ์ปฌ๋ผ๋ค์ ํ๋๋ก ์ ์ํด์ Column ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
from sqlalchemy import String, Integer, Column
from .base import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String(30), nullable=True)
age = Column(Integer, nullable=False, default=0)

ํ ์ด๋ธ ๋๊ธฐํํ๊ธฐ
์ํฐํฐ๋ฅผ ์ ์ํ์ผ๋, ๊ทธ๊ฒ ์ค์ ํ
์ด๋ธ๋ก ์๊ฒจ๋๋๋ก ๋๊ธฐํ๋ฅผ ํด๋ณด์.
importํด์จ ์ํ์์ sync_db๋ฅผ ํด์ฃผ๋ฉด

์ฃผ๋ฅด๋ฅต ๋จ๋ฉด์

์ด๋ ๊ฒ ๋ง๋ค์ด์ค๋ค.
๋ฐ์ดํฐ ์ฝ์ ํ๊ธฐ (add, add_all)
์ด์ ๋ ๋ง๋ค์ด๋จ๋๊ฑธ ๊ธฐ๋ฐ์ผ๋ก CRUD ์์ ์ ํ๋์ฉ ํด๋ณด๊ฒ ๋ค.
์ธ์ ์ ๊ฐ์ ธ์์ ์ด๋์ ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , add๋ก ์ถ๊ฐํ๊ณ , ์ปค๋ฐ์น๊ณ , ์ธ์ ์ ๋ซ์ผ๋ฉด ๋๋ค.
from models import user, base
def main():
db_session = base.get_db_session()
new_user = user.User(name="John Doe", age=555)
db_session.add(new_user)
db_session.commit()
db_session.close()
main()
์ปค๋ฐ์ ์ณ์ผ๋จ ์ง์ง ์ปค๋ฐ์ด ๋ค์ด๊ฐ๋ค๋ ์ ์์ง ๋ง์.
์ธ์
๋ ๊ผญ ๋ซ์์ฃผ์.
์๋ฌดํผ ์ ๋ ๊ฒ ์คํํ๋ฉด

๊ธฐ๋ํ๋๋ก ๋ค์ด๊ฐ ๊ฒ์ด๋ค.
๋ฐฐ์ด๋ก ๋ง๋ค์ด์ add_all์ ํ๋ฉด ์ฌ๋ฌ๊ฐ๋ฅผ ํ๋ฒ์ ๋ฃ์ ์ ์๋ค.
from models import user, base
def main():
db_session = base.get_db_session()
users = [
user.User(name="John Doe", age=555),
user.User(name="Phone Doe", age=666),
user.User(name="Alexander", age=444),
user.User(name="Jane Doe", age=10)
]
db_session.add_all(users)
db_session.commit()
db_session.close()
main()

์ ๋ค์ด๊ฐ๋ค.
๋ฐ์ดํฐ ์กฐํํ๊ธฐ
์กฐํ๋ฅผ ํ ๋๋ ์ฃผ๋ก query ํจ์๋ฅผ ์ฌ์ฉํด์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
์๋๋ id๊ฐ 1์ธ ๊ฐ์ฒด๋ง ํ๋ ์ฐพ์์ค๋ ๊ฐ๋จํ ์์ ๋ค.
from models import user, base
from sqlalchemy.engine.row import Row
def main():
db_session = base.get_db_session()
result = db_session.query(user.User).filter_by(id = 1).first()
print(result.id, result.name, result.age)
db_session.close()
main()
์ฌ๊ธฐ์ ์ ์ํ ์ ์, query๋ filter_by ๊ฐ์๊ฑด ๊ทธ๋ฅ ์ฟผ๋ฆฌ ํ
์คํธ๋ง ๋ง๋ค์ด์ฃผ๋ ์ญํ ์ด๋ ๊ฒ์ด๋ค.
์ ๋ฐ ๋ฉ์๋ ์ฒด์ด๋์ ํตํด์ ์์ฑํ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ, first๋ all ๋ฑ์ ํจ์๋ก ์คํ์ํค๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์จ๋ค.
all์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ๊ฐ๋ฅผ ๋ฆฌ์คํธ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ค.
์๋ ์ฝ๋๋ age๊ฐ 555, 666, 777์ธ ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ selectํด์ค๋ ์ฝ๋๋ค.
from models import user, base
from sqlalchemy.engine.row import Row
def main():
db_session = base.get_db_session()
result = db_session.query(user.User) \
.where(user.User.age.in_([555, 666, 777])) \
.all()
for e in result:
print(e.id, e.name, e.age)
db_session.close()
main()
์ ๊ฐ์ ธ์จ๋ค.
๋ฐ์ดํฐ ์์ ํ๊ธฐ (update)
๋ฐ์ดํฐ์ update๋ฅผ ์น๋๊ฒ์๋ ํฌ๊ฒ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
์ ์งํ๊ฒ update ํจ์๋ฅผ ํธ์ถํด์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์๊ณ
from models import user, base
from sqlalchemy.engine.row import Row
def main():
db_session = base.get_db_session()
result = db_session.query(user.User) \
.where(user.User.id.__eq__(1)) \
.update({"name": "FooBar"})
db_session.commit()
db_session.close()
main()


select๋ก ๊ฐ์ ธ์จ ๊ฐ์์ ํ๋๋ง ์กฐ์ํด์ ์ผ๋ ๋ฑ๋ ์์ ๋๊ฒ ํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
from models import user, base
from sqlalchemy.engine.row import Row
def main():
db_session = base.get_db_session()
found = db_session.query(user.User) \
.where(user.User.id.__eq__(3)) \
.first()
found.name = "asdf" // ๊ฐ ๋ณ๊ฒฝ!
db_session.commit() // DB์ ๋ฐ์!
db_session.close()
main()


๋ฐ์ดํฐ ์ญ์ ํ๊ธฐ (delete)
์ด๋ฒ์๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ ์ง์๋ณด์.
update ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ๊ณผ ๋ณ๋ฐ ๋ค๋ฅผ ๊ฒ์ ์๋ค.
from models import user, base
from sqlalchemy.engine.row import Row
def main():
db_session = base.get_db_session()
result = db_session.query(user.User) \
.where(user.User.id.__eq__(2)) \
.delete()
db_session.commit()
db_session.close()
main()
ํด์ ์คํ์ํค๋ฉด

์ ์ฌ๋ผ์ง๋ค.

์ฐธ์กฐ
https://www.sqlalchemy.org/
https://blog.neonkid.xyz/253