SQLAlchemy Core์ ORM์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ ์ฐจ์ด๋ฅผ ํ๊ตฌํฉ๋๋ค. ๊ฐ ์ ๊ทผ ๋ฐฉ์์ ์ฟผ๋ฆฌ ๊ตฌ์ฑ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๊ณ , ์ฑ๋ฅ, ์ ์ฐ์ฑ ๋ฐ ์ฌ์ฉ ํธ์์ฑ์ ๋น๊ต ๋ถ์ํฉ๋๋ค.
SQLAlchemy Core vs ORM: ์์ธ ์ฟผ๋ฆฌ ๊ตฌ์ฑ ๋น๊ต
SQLAlchemy๋ Python์ ์ํ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ SQL ํดํท์ด์ ๊ฐ์ฒด ๊ด๊ณํ ๋งคํผ(ORM)์ ๋๋ค. ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ ๋ ๊ฐ์ง ๋ ํนํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค: SQLAlchemy Core์ SQLAlchemy ORM. ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์ ๊ฐ์ ์ฐจ์ด๋ฅผ ์ดํดํ๋ ๊ฒ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ง๋ ์ฌ๋ฐ๋ฅธ ๋๊ตฌ๋ฅผ ์ ํํ๋ ๋ฐ ์ค์ํฉ๋๋ค. ์ด ๊ธ์์๋ ์ฑ๋ฅ, ์ ์ฐ์ฑ ๋ฐ ์ฌ์ฉ ํธ์์ฑ์ ์ด์ ์ ๋ง์ถฐ SQLAlchemy Core์ ORM์ ์ฌ์ฉํ ์ฟผ๋ฆฌ ๊ตฌ์ฑ์ ๋ํ ํฌ๊ด์ ์ธ ๋น๊ต๋ฅผ ์ ๊ณตํฉ๋๋ค.
SQLAlchemy Core ์ดํดํ๊ธฐ
SQLAlchemy Core๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ๋ ์ง์ ์ ์ด๊ณ ๋ช ์์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ์ ์ํ๊ณ SQL ๋ฌธ์ ์ง์ ์คํํ ์ ์์ต๋๋ค. ์ด๋ ๋ณธ์ง์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ธฐ๋ณธ SQL ๋ฐฉ์ธ ์์ ์๋ ์ถ์ํ ๊ณ์ธต์ผ๋ก, SQL์ ๊ตฌ์ฑํ๊ณ ์คํํ๋ Pythonic ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค.
SQLAlchemy Core์ ์ฃผ์ ํน์ง:
- ๋ช ์์ ์ธ SQL: SQL ๋ฌธ์ ์ง์ ์์ฑํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ ๋ํ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ํ์ ์์ค ์ถ์ํ: ์์ ์ถ์ํ ๊ณ์ธต์ ์ ๊ณตํ์ฌ ์ค๋ฒํค๋๋ฅผ ์ต์ํํ๊ณ ์ฑ๋ฅ์ ๊ทน๋ํํฉ๋๋ค.
- ๋ฐ์ดํฐ ์ค์ฌ: ์ฃผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ๋๋ ํํ ํ์์ ํ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ฐ์ด๋ ์ ์ฐ์ฑ: ๋ณต์กํ ์ฟผ๋ฆฌ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ๊ธฐ๋ฅ์ ๋ํด ์ต๋์ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค.
SQLAlchemy ORM ์ดํดํ๊ธฐ
SQLAlchemy ORM(๊ฐ์ฒด ๊ด๊ณํ ๋งคํผ)์ Python ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ์์ฉํ ์ ์๋๋ก ํ๋ ์์ ์์ค ์ถ์ํ ๊ณ์ธต์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ Python ํด๋์ค์ ๋งคํํ์ฌ ๊ฐ์ฒด ์งํฅ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ ํ ์ ์๊ฒ ํฉ๋๋ค.
SQLAlchemy ORM์ ์ฃผ์ ํน์ง:
- ๊ฐ์ฒด ์งํฅ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ ๋ํ๋ด๋ Python ๊ฐ์ฒด๋ฅผ ํตํด ๋ฐ์ดํฐ์ ์ํธ์์ฉํฉ๋๋ค.
- ์์ ์์ค ์ถ์ํ: ๋ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์๋ํํ์ฌ ๊ฐ๋ฐ์ ๋จ์ํํฉ๋๋ค.
- ๊ฐ์ฒด ์ค์ฌ: ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ์ฒ๋ฆฌํ์ฌ ์บก์ํ ๋ฐ ์์์ ์ ๊ณตํฉ๋๋ค.
- ๋จ์ํ๋ ๊ฐ๋ฐ: ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ๋จ์ํํ๊ณ ์ํฌ์ ์ธ ์ฝ๋(boilerplate code)๋ฅผ ์ค์ฌ์ค๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ (๊ณตํต ๋ถ๋ถ)
์ฟผ๋ฆฌ ๊ตฌ์ฑ ๋น๊ต์ ์์, SQLAlchemy๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ ์ค์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์์ฐ ๋ชฉ์ ์ผ๋ก SQLite๋ฅผ ์ฌ์ฉํ์ง๋ง, ๊ฐ๋ ์ ์ฌ์ํ ๋ฐฉ์ธ๋ณ ์กฐ์ ์ ํตํด ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ (์: PostgreSQL, MySQL, Oracle)์๋ ์ ์ฉ๋ฉ๋๋ค. `id`, `name`, `email` ์ด์ ๊ฐ์ง `users` ํ ์ด๋ธ์ ์์ฑํ ๊ฒ์ ๋๋ค.
๋จผ์ , SQLAlchemy๋ฅผ ์ค์นํฉ๋๋ค:
pip install sqlalchemy
์ด์ Core ๋ฐ ORM ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ํ ์ด๋ธ์ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ์ด๊ธฐ ์ค์ ์ ํ ์ด๋ธ์ด ์ ์๋๋ ๋ฐฉ์์ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ค๋๋ค.
Core ์ค์
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///:memory:') # In-memory database for example
metadata = MetaData()
users_table = Table(
'users',
metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50)),
Column('email', String(100))
)
metadata.create_all(engine)
connection = engine.connect()
ORM ์ค์
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
engine = create_engine('sqlite:///:memory:')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
email = Column(String(100))
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
Core ์์ ์์๋ `Table` ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ด๋ธ์ ์ง์ ์ ์ํฉ๋๋ค. ORM ์์ ์์๋ `users` ํ ์ด๋ธ์ ๋งคํ๋๋ Python ํด๋์ค `User`๋ฅผ ์ ์ํฉ๋๋ค. ORM์ ํด๋์ค ์ ์๋ฅผ ํตํด ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ธฐ ์ํด ์ ์ธ์ ๊ธฐ๋ฐ(declarative base)์ ์ฌ์ฉํฉ๋๋ค.
์ฟผ๋ฆฌ ๊ตฌ์ฑ ๋น๊ต
์ด์ SQLAlchemy Core์ ORM์ ์ฌ์ฉํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค. ๋ฐ์ดํฐ ์ ํ, ๋ฐ์ดํฐ ํํฐ๋ง, ๋ฐ์ดํฐ ์ฝ์ , ๋ฐ์ดํฐ ์ ๋ฐ์ดํธ ๋ฐ ๋ฐ์ดํฐ ์ญ์ ์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์ฟผ๋ฆฌ ์์ ์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
๋ฐ์ดํฐ ์ ํ
SQLAlchemy Core:
from sqlalchemy import select
# Select all users
select_stmt = select(users_table)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
# Select specific columns (name and email)
select_stmt = select(users_table.c.name, users_table.c.email)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
SQLAlchemy ORM:
# Select all users
users = session.query(User).all()
for user in users:
print(user.name, user.email)
# Select specific columns (name and email)
users = session.query(User.name, User.email).all()
for user in users:
print(user)
Core์์๋ `select` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ํํ ํ ์ด๋ธ ๋๋ ์ด์ ์ง์ ํฉ๋๋ค. `users_table.c.column_name`์ ์ฌ์ฉํ์ฌ ์ด์ ์ ๊ทผํฉ๋๋ค. ๊ฒฐ๊ณผ๋ ํ์ ๋ํ๋ด๋ ํํ ๋ชฉ๋ก์ ๋๋ค. ORM์์๋ `session.query(User)`๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ์ ํํ๊ณ , ๊ฐ์ฒด ์์ฑ(์: `user.name`)์ ์ฌ์ฉํ์ฌ ์ด์ ์ ๊ทผํฉ๋๋ค. ๊ฒฐ๊ณผ๋ `User` ๊ฐ์ฒด์ ๋ชฉ๋ก์ ๋๋ค. ORM์ด ํ ์ด๋ธ ์ด๊ณผ ๊ฐ์ฒด ์์ฑ ๊ฐ์ ๋งคํ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ค๋ ์ ์ ์ ์ํ์ญ์์ค.
๋ฐ์ดํฐ ํํฐ๋ง (WHERE ์ )
SQLAlchemy Core:
from sqlalchemy import select, and_, or_
# Select users with name 'Alice'
select_stmt = select(users_table).where(users_table.c.name == 'Alice')
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
# Select users with name 'Alice' and email containing 'example.com'
select_stmt = select(users_table).where(
and_(
users_table.c.name == 'Alice',
users_table.c.email.like('%example.com%')
)
)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
SQLAlchemy ORM:
# Select users with name 'Alice'
users = session.query(User).filter(User.name == 'Alice').all()
for user in users:
print(user.name, user.email)
# Select users with name 'Alice' and email containing 'example.com'
users = session.query(User).filter(
User.name == 'Alice',
User.email.like('%example.com%')
).all()
for user in users:
print(user.name, user.email)
Core์์๋ `where` ์ ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํฉ๋๋ค. `and_` ๋ฐ `or_`์ ๊ฐ์ ๋ ผ๋ฆฌ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ์กฐ๊ฑด์ ๊ฒฐํฉํ ์ ์์ต๋๋ค. ORM์์๋ `filter` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉฐ, ์ด๋ ํํฐ ์กฐ๊ฑด์ ์ง์ ํ๋ ๋ ๊ฐ์ฒด ์งํฅ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ฌ๋ฌ `filter` ํธ์ถ์ `and_`๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค.
๋ฐ์ดํฐ ์ ๋ ฌ (ORDER BY ์ )
SQLAlchemy Core:
from sqlalchemy import select
# Select users ordered by name (ascending)
select_stmt = select(users_table).order_by(users_table.c.name)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
# Select users ordered by name (descending)
from sqlalchemy import desc
select_stmt = select(users_table).order_by(desc(users_table.c.name))
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
SQLAlchemy ORM:
# Select users ordered by name (ascending)
users = session.query(User).order_by(User.name).all()
for user in users:
print(user.name, user.email)
# Select users ordered by name (descending)
from sqlalchemy import desc
users = session.query(User).order_by(desc(User.name)).all()
for user in users:
print(user.name, user.email)
Core์ ORM ๋ชจ๋์์ `order_by` ์ ์ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ ฌํฉ๋๋ค. `desc` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ด๋ฆผ์ฐจ์์ ์ง์ ํ ์ ์์ต๋๋ค. ๊ตฌ๋ฌธ์ ๋งค์ฐ ์ ์ฌํ์ง๋ง, ORM์ ์ด ์ฐธ์กฐ์ ๊ฐ์ฒด ์์ฑ์ ์ฌ์ฉํฉ๋๋ค.
๊ฒฐ๊ณผ ์ ํ (LIMIT ๋ฐ OFFSET ์ )
SQLAlchemy Core:
from sqlalchemy import select
# Select the first 5 users
select_stmt = select(users_table).limit(5)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
# Select users starting from the 6th user (offset 5), limit 5
select_stmt = select(users_table).offset(5).limit(5)
result = connection.execute(select_stmt)
users = result.fetchall()
for user in users:
print(user)
SQLAlchemy ORM:
# Select the first 5 users
users = session.query(User).limit(5).all()
for user in users:
print(user.name, user.email)
# Select users starting from the 6th user (offset 5), limit 5
users = session.query(User).offset(5).limit(5).all()
for user in users:
print(user.name, user.email)
Core์ ORM ๋ชจ๋ `limit` ๋ฐ `offset` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐํ๋๋ ๊ฒฐ๊ณผ์ ์๋ฅผ ์ ์ดํฉ๋๋ค. ๊ตฌ๋ฌธ์ ๊ฑฐ์ ๋์ผํฉ๋๋ค.
ํ ์ด๋ธ ์กฐ์ธ (JOIN ์ )
ํ ์ด๋ธ ์กฐ์ธ์ Core์ ORM ๊ฐ์ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ ๋ณต์กํ ์์ ์ ๋๋ค. `id`, `user_id`, `address` ์ด์ ๊ฐ์ง `addresses`๋ผ๋ ๋ ๋ฒ์งธ ํ ์ด๋ธ์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
SQLAlchemy Core:
from sqlalchemy import Table, Column, Integer, String, ForeignKey
addresses_table = Table(
'addresses',
metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id')),
Column('address', String(200))
)
metadata.create_all(engine)
# Select users and their addresses
select_stmt = select(users_table, addresses_table).where(users_table.c.id == addresses_table.c.user_id)
result = connection.execute(select_stmt)
users_addresses = result.fetchall()
for user, address in users_addresses:
print(user.name, address.address)
SQLAlchemy ORM:
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
address = Column(String(200))
user = relationship("User", back_populates="addresses") # Define relationship with User
User.addresses = relationship("Address", back_populates="user")
Base.metadata.create_all(engine)
# Select users and their addresses
users = session.query(User).all()
for user in users:
for address in user.addresses:
print(user.name, address.address)
Core์์๋ `where` ์ ์ ์ฌ์ฉํ์ฌ ์กฐ์ธ ์กฐ๊ฑด์ ๋ช ์์ ์ผ๋ก ์ง์ ํฉ๋๋ค. ๊ฒฐ๊ณผ๋ฅผ ํํ๋ก ๊ฒ์ํ๊ณ ์ธ๋ฑ์ค๋ฅผ ํตํด ์ด์ ์ ๊ทผํฉ๋๋ค. ORM์์๋ `relationship` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ `User`์ `Address` ํด๋์ค ๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํฉ๋๋ค. ์ด๋ฅผ ํตํด `user.addresses` ์์ฑ์ ํตํด ์ฌ์ฉ์์ ๊ด๋ จ๋ ์ฃผ์์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค. ORM์ ์กฐ์ธ์ ์์์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. `back_populates` ์ธ์๋ ๊ด๊ณ์ ์์ชฝ์ ๋๊ธฐํ ์ํ๋ก ์ ์งํฉ๋๋ค.
๋ฐ์ดํฐ ์ฝ์
SQLAlchemy Core:
from sqlalchemy import insert
# Insert a new user
insert_stmt = insert(users_table).values(name='Bob', email='bob@example.com')
result = connection.execute(insert_stmt)
# Get the ID of the newly inserted row
inserted_id = result.inserted_primary_key[0]
print(f"Inserted user with ID: {inserted_id}")
connection.commit()
SQLAlchemy ORM:
# Insert a new user
new_user = User(name='Bob', email='bob@example.com')
session.add(new_user)
session.commit()
# Get the ID of the newly inserted row
print(f"Inserted user with ID: {new_user.id}")
Core์์๋ `insert` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ์ ํ ๊ฐ์ ์ ๊ณตํฉ๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ ์ ์งํ๋ ค๋ฉด ํธ๋์ญ์ ์ ์ปค๋ฐํด์ผ ํฉ๋๋ค. ORM์์๋ `User` ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์ธ์ ์ ์ถ๊ฐํ ๋ค์ ์ธ์ ์ ์ปค๋ฐํฉ๋๋ค. ORM์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋์ผ๋ก ์ถ์ ํ๊ณ ์ฝ์ ํ๋ก์ธ์ค๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ์ปค๋ฐ ํ `new_user.id`์ ์ ๊ทผํ๋ฉด ํ ๋น๋ ๊ธฐ๋ณธ ํค๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ์ ๋ฐ์ดํธ
SQLAlchemy Core:
from sqlalchemy import update
# Update the email of user with ID 1
update_stmt = update(users_table).where(users_table.c.id == 1).values(email='new_email@example.com')
result = connection.execute(update_stmt)
print(f"Updated {result.rowcount} rows")
connection.commit()
SQLAlchemy ORM:
# Update the email of user with ID 1
user = session.query(User).filter(User.id == 1).first()
if user:
user.email = 'new_email@example.com'
session.commit()
print("User updated successfully")
else:
print("User not found")
Core์์๋ `update` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฐ์ดํธํ ์ด๊ณผ where ์ ์ ์ง์ ํฉ๋๋ค. ํธ๋์ญ์ ์ ์ปค๋ฐํด์ผ ํฉ๋๋ค. ORM์์๋ `User` ๊ฐ์ฒด๋ฅผ ๊ฒ์ํ๊ณ , ํด๋น ์์ฑ์ ์์ ํ ๋ค์ ์ธ์ ์ ์ปค๋ฐํฉ๋๋ค. ORM์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋์ผ๋ก ์ถ์ ํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํด๋น ํ์ ์ ๋ฐ์ดํธํฉ๋๋ค.
๋ฐ์ดํฐ ์ญ์
SQLAlchemy Core:
from sqlalchemy import delete
# Delete user with ID 1
delete_stmt = delete(users_table).where(users_table.c.id == 1)
result = connection.execute(delete_stmt)
print(f"Deleted {result.rowcount} rows")
connection.commit()
SQLAlchemy ORM:
# Delete user with ID 1
user = session.query(User).filter(User.id == 1).first()
if user:
session.delete(user)
session.commit()
print("User deleted successfully")
else:
print("User not found")
Core์์๋ `delete` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ where ์ ์ ์ง์ ํฉ๋๋ค. ํธ๋์ญ์ ์ ์ปค๋ฐํด์ผ ํฉ๋๋ค. ORM์์๋ `User` ๊ฐ์ฒด๋ฅผ ๊ฒ์ํ๊ณ , ์ธ์ ์์ ์ญ์ ํ ๋ค์ ์ธ์ ์ ์ปค๋ฐํฉ๋๋ค. ORM์ ์ญ์ ํ๋ก์ธ์ค๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
์ฑ๋ฅ ๊ณ ๋ ค ์ฌํญ
SQLAlchemy Core๋ ์ต์ ํ๋ SQL ๋ฌธ์ ์ง์ ์์ฑํ ์ ์์ผ๋ฏ๋ก ๋ณต์กํ ์ฟผ๋ฆฌ์ ๋ํด ์ผ๋ฐ์ ์ผ๋ก ๋ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ์ฒด ์งํฅ ์์ ์ SQL๋ก ๋ณํํ๋ ๋ฐ ๊ด๋ จ๋ ์ค๋ฒํค๋๊ฐ ์ ์ต๋๋ค. ํ์ง๋ง ์ด๋ ๊ฐ๋ฐ ๋ ธ๋ ฅ ์ฆ๊ฐ๋ผ๋ ๋๊ฐ๋ฅผ ์น๋ฆ ๋๋ค. ์์ SQL์ ๋๋๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ์ด๋ฉฐ ์ด์์ฑ์ด ๋จ์ด์ง ์ ์์ต๋๋ค.
SQLAlchemy ORM์ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ ๋งคํํ๋ ์ค๋ฒํค๋ ๋๋ฌธ์ ํน์ ์์ ์์ ๋ ๋๋ฆด ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ง์ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์์ ์ฑ๋ฅ ์ฐจ์ด๋ ๋ฏธ๋ฏธํ๋ฉฐ, ๋จ์ํ๋ ๊ฐ๋ฐ์ ์ด์ ์ด ์ฑ๋ฅ ๋น์ฉ๋ณด๋ค ํฝ๋๋ค. ORM์ ๋ํ ์ผ๋ถ ์๋๋ฆฌ์ค์์ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์๋ ์บ์ฑ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ ๊ทน์ ๋ก๋ฉ(`joinedload`, `subqueryload`)๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด ๊ด๋ จ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ ๋ ์ฑ๋ฅ์ ํฌ๊ฒ ์ต์ ํํ ์ ์์ต๋๋ค.
์ฅ๋จ์ :
- Core: ๋ ๋น ๋ฅธ ์คํ ์๋, ๋ ๋ง์ ์ ์ด, ๊ฐํ๋ฅธ ํ์ต ๊ณก์ , ๋ ์ฅํฉํ ์ฝ๋.
- ORM: ๋ ๋๋ฆฐ ์คํ ์๋(์ ์ฌ์ ์ผ๋ก), ๋ ์ ์ ์ ์ด, ๋ฐฐ์ฐ๊ธฐ ์ฌ์, ๋ ๊ฐ๊ฒฐํ ์ฝ๋.
์ ์ฐ์ฑ ๊ณ ๋ ค ์ฌํญ
SQLAlchemy Core๋ SQL ๋ฌธ์ ๋ํ ์์ ํ ์ ์ด๊ถ์ ๊ฐ์ง๋ฏ๋ก ์ต๋์ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ณต์กํ ์ฟผ๋ฆฌ, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ๊ธฐ๋ฅ ๋๋ ์ฑ๋ฅ์ ์ค์ํ ์์ ์ ํนํ ์ค์ํฉ๋๋ค. ์๋์ฐ ํจ์, ๊ณตํต ํ ์ด๋ธ ํํ์(CTE) ๋ฐ ์ ์ฅ ํ๋ก์์ ์ ๊ฐ์ ๊ณ ๊ธ SQL ๊ธฐ๋ฅ์ ์ง์ ํ์ฉํ ์ ์์ต๋๋ค.
SQLAlchemy ORM์ ๊ธฐ๋ณธ SQL์ ์ถ์ํํ๋ฏ๋ก ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋๋ค. ๋ง์ ์ผ๋ฐ์ ์ธ SQL ๊ธฐ๋ฅ์ ์ง์ํ์ง๋ง, ๊ณ ๋๋ก ํนํ๋๊ฑฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ์์ ์๋ ์ ํฉํ์ง ์์ ์ ์์ต๋๋ค. ORM์ด ํ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง ์๋ ๊ฒฝ์ฐ ํน์ ์์ ์ ๋ํด Core๋ก ์ ํํด์ผ ํ ์๋ ์์ต๋๋ค. SQLAlchemy๋ ๋์ผํ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ Core์ ORM์ ํผํฉํ์ฌ ์ฌ์ฉํ ์ ์๋๋ก ํ์ฌ ์์ชฝ์ ์ฅ์ ์ ๋ชจ๋ ์ ๊ณตํฉ๋๋ค.
์ฌ์ฉ ํธ์์ฑ ๊ณ ๋ ค ์ฌํญ
SQLAlchemy ORM์ ํนํ ๊ฐ๋จํ CRUD(์์ฑ, ์ฝ๊ธฐ, ์ ๋ฐ์ดํธ, ์ญ์ ) ์์ ์์ SQLAlchemy Core๋ณด๋ค ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ฝ์ต๋๋ค. ๊ฐ์ฒด ์งํฅ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ๋ฐ์ ๋จ์ํํ๊ณ ์ํฌ์ ์ธ ์ฝ๋(boilerplate code)๋ฅผ ์ค์ฌ์ค๋๋ค. SQL ๊ตฌ๋ฌธ์ ์ธ๋ถ ์ฌํญ๋ณด๋ค๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง์ ์ง์คํ ์ ์์ต๋๋ค.
SQLAlchemy Core๋ SQL ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ๋ ์ ๋ํ ๋ ๊น์ ์ดํด๋ฅผ ํ์๋ก ํฉ๋๋ค. ORM๊ณผ ๋์ผํ ์์ ์ ์ํํ๋ ๋ฐ ๋ ์ฅํฉํ๊ณ ๋ ๋ง์ ์ฝ๋๋ฅผ ์๊ตฌํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ ๋ํ ๋ ๋ง์ ์ ์ด์ ๊ฐ์์ฑ์ ์ ๊ณตํฉ๋๋ค.
Core vs. ORM ์ฌ์ฉ ์๊ธฐ
SQLAlchemy Core๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ:
- ์ต๋ ์ฑ๋ฅ๊ณผ SQL์ ๋ํ ์ ์ด๊ฐ ํ์ํ ๋.
- ๋ณต์กํ ์ฟผ๋ฆฌ ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ๊ธฐ๋ฅ์ ๋ค๋ฃฐ ๋.
- SQL ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ๋ ์ ๋ํ ๊น์ ์ดํด๊ฐ ์์ ๋.
- ๊ฐ์ฒด ๋งคํ์ ์ค๋ฒํค๋๊ฐ ํ์ฉ๋์ง ์์ ๋.
- ๋ณต์กํ ์คํค๋ง๋ฅผ ๊ฐ์ง ๋ ๊ฑฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์์ ํ ๋.
SQLAlchemy ORM์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ:
- ์ฌ์ฉ ํธ์์ฑ๊ณผ ๋น ๋ฅธ ๊ฐ๋ฐ์ ์ฐ์ ์ํ ๋.
- ์ ์ ์๋ ๊ฐ์ฒด ๋ชจ๋ธ์ ๊ฐ์ง ์๋ก์ด ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ํ ๋.
- ์ผ๋ฐ์ ์ธ CRUD ์์ ์ ๋จ์ํํด์ผ ํ ๋.
- ์ฑ๋ฅ์ด ์ฃผ์ ๊ด์ฌ์ฌ๊ฐ ์๋ ๋ (๋๋ ์บ์ฑ ๋ฐ ์ ๊ทน์ ๋ก๋ฉ์ผ๋ก ์ต์ ํํ ์ ์์ ๋).
- ์บก์ํ ๋ฐ ์์๊ณผ ๊ฐ์ ๊ฐ์ฒด ์งํฅ ๊ธฐ๋ฅ์ ํ์ฉํ๊ณ ์ถ์ ๋.
์ค์ ์ฌ๋ก ๋ฐ ๊ณ ๋ ค ์ฌํญ
๋ช ๊ฐ์ง ์ค์ ์๋๋ฆฌ์ค์ Core์ ORM ์ฌ์ด์ ์ ํ์ด ์ด๋ป๊ฒ ์ํฅ์ ๋ฐ์ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค:
-
์ ์ ์๊ฑฐ๋ ํ๋ซํผ: ์๋ฐฑ๋ง ๊ฐ์ ์ ํ๊ณผ ๊ณ ๊ฐ ๊ฑฐ๋๋ฅผ ๊ด๋ฆฌํ๋ ์ ์ ์๊ฑฐ๋ ํ๋ซํผ์ ํต์ฌ ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์ SQLAlchemy Core๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ ๋ฆฌํ ์ ์์ต๋๋ค. ํนํ ์ ํ ๊ฒ์ ๋ฐ ์ฃผ๋ฌธ ์ฒ๋ฆฌ์ ๊ฐ์ ์ฑ๋ฅ์ด ์ค์ํ ์ฟผ๋ฆฌ์ ๋ํด์๋ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. ORM์ ์ฌ์ฉ์ ํ๋กํ ๋ฐ ์ ํ ์นดํ ๊ณ ๋ฆฌ ๊ด๋ฆฌ์ ๊ฐ์ด ๋ ์ค์ํ ์์ ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
-
๋ฐ์ดํฐ ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ : ๋ณต์กํ ์ง๊ณ ๋ฐ ๋ฐ์ดํฐ ๋ณํ์ด ํ์ํ ๋ฐ์ดํฐ ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ SQLAlchemy Core๋ฅผ ํ์ฉํ์ฌ ๊ณ ๋๋ก ์ต์ ํ๋ SQL ์ฟผ๋ฆฌ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ณ ๋ถ์ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
-
์ฝํ ์ธ ๊ด๋ฆฌ ์์คํ (CMS): ๊ธฐ์ฌ, ํ์ด์ง ๋ฐ ๋ฏธ๋์ด ์์ฐ์ ๊ด๋ฆฌํ๋ CMS๋ SQLAlchemy ORM์ ์ฝํ ์ธ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ์ฌ ์ฝํ ์ธ ์์ฑ, ํธ์ง ๋ฐ ๊ฒ์์ ๋จ์ํํ ์ ์์ต๋๋ค. Core๋ ์ฌ์ฉ์ ์ ์ ๊ฒ์ ๊ธฐ๋ฅ ๋๋ ๋ณต์กํ ์ฝํ ์ธ ๊ด๊ณ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
-
๊ธ์ต ๊ฑฐ๋ ์์คํ : ์ด๊ณ ๋น๋ ๊ฑฐ๋ ์์คํ ์ ๊ทน์ฌํ ์ง์ฐ ์๊ฐ ๋ฏผ๊ฐ์ฑ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ ๋ํ ์ธ๋ฐํ ์ ์ด์ ํ์์ฑ ๋๋ฌธ์ ๊ฑฐ์ ํ์คํ SQLAlchemy Core๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๋๋ค. ๋งค ๋ง์ดํฌ๋ก์ด๊ฐ ์ค์ํฉ๋๋ค!
-
์์ ๋ฏธ๋์ด ํ๋ซํผ: ์์ ๋ฏธ๋์ด ํ๋ซํผ์ ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ๊ณ์ , ๊ฒ์๋ฌผ ๋ฐ ๋๊ธ ๊ด๋ฆฌ๋ฅผ ์ํด ORM์ ์ฌ์ฉํ๊ณ , ์ฌ์ฉ์ ๊ฐ์ ์ฐ๊ฒฐ์ ์ฐพ๊ฑฐ๋ ํธ๋ ๋๋ฅผ ๋ถ์ํ๋ ๋ณต์กํ ๊ทธ๋ํ ์ฟผ๋ฆฌ๋ฅผ ์ํด Core๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ตญ์ ํ ๊ณ ๋ ค ์ฌํญ: ์ ์ญ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ ์ค๊ณํ ๋, ์ฌ๋ฌ ์ธ์ด๋ฅผ ์ง์ํ๊ธฐ ์ํด ์ ๋์ฝ๋ ๋ฐ์ดํฐ ์ ํ(์: `NVARCHAR`)์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. SQLAlchemy๋ ์ ๋์ฝ๋ ์ธ์ฝ๋ฉ์ ํฌ๋ช ํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค. ๋ํ ๋ ์ง์ ์๊ฐ์ ํ์คํ๋ ํ์(์: UTC)์ผ๋ก ์ ์ฅํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ๊ณ์ธต์์ ์ฌ์ฉ์ ํ์ง ์๊ฐ๋๋ก ๋ณํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
๊ฒฐ๋ก
SQLAlchemy Core์ ORM์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ ๋ํ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์ ๊ณตํ๋ฉฐ, ๊ฐ๊ฐ ๊ณ ์ ํ ์ฅ๋จ์ ์ ๊ฐ์ง๋๋ค. SQLAlchemy Core๋ ์ต๋ ์ฑ๋ฅ๊ณผ ์ ์ฐ์ฑ์ ์ ๊ณตํ๋ ๋ฐ๋ฉด, SQLAlchemy ORM์ ๊ฐ๋ฐ์ ๋จ์ํํ๊ณ ๊ฐ์ฒด ์งํฅ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค. Core์ ORM ์ค ์ด๋ค ๊ฒ์ ์ ํํ ์ง๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ๋ง์ ๊ฒฝ์ฐ, Core์ ORM์ ๊ฐ์ ์ ๊ฒฐํฉํ ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์์ด ์ต์ ์ ํด๊ฒฐ์ฑ ์ ๋๋ค. ๊ฐ ์ ๊ทผ ๋ฐฉ์์ ๋ฏธ๋ฌํ ์ฐจ์ด๋ฅผ ์ดํดํ๋ฉด ์ ๋ณด์ ์ ๊ฐํ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ณ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. SQLAlchemy Core์ ORM ์ค์์ ์ ํํ ๋๋ ์ฑ๋ฅ ์ํฅ, ์ ์ฐ์ฑ ์๊ตฌ ์ฌํญ ๋ฐ ์ฌ์ฉ ํธ์์ฑ์ ๊ณ ๋ คํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.