Notes & software courses · Free to learn
Aph's Blog
On this page

ORM (SQLAlchemy)

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

map class ของ Python เข้ากับตารางในฐานข้อมูล เขียน CRUD ด้วยโค้ด Python แทน SQL ดิบ

ORM (Object-Relational Mapping) คือเครื่องมือที่ทำให้เราทำงานกับฐานข้อมูลผ่าน object/class ของ Python แทนการเขียน SQL ดิบทุกครั้ง — แต่ละแถวกลายเป็น object หนึ่งตัว ทำให้โค้ดอ่านง่ายและจัดการง่ายขึ้น

ORM map class ↔ table

หลักการ: 1 class = 1 ตาราง, 1 object = 1 แถว, attribute = คอลัมน์ ตัวอย่างใช้ SQLAlchemy (ORM ยอดนิยมของ Python)

python
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session

class Base(DeclarativeBase):
    pass

class User(Base):                       # class = ตาราง
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(50))
    age: Mapped[int]

engine = create_engine("sqlite:///app.db")
Base.metadata.create_all(engine)        # สร้างตารางจาก class

CRUD ผ่าน ORM

python
from sqlalchemy import select

with Session(engine) as session:
    # Create — สร้าง object แล้ว add
    user = User(name="Aph", age=25)
    session.add(user)
    session.commit()

    # Read — query ด้วย object ไม่ใช่ SQL
    result = session.scalars(select(User).where(User.age >= 18))
    for u in result:
        print(u.name, u.age)

    # Update — แก้ attribute แล้ว commit
    u = session.get(User, 1)
    u.age = 26
    session.commit()

    # Delete
    session.delete(u)
    session.commit()

ORM vs raw SQL — เลือกยังไง

ORMraw SQL
เขียนโค้ด Python (object)SQL string
อ่านง่ายดีกับงานทั่วไปดีกับ query ซับซ้อน
ปลอดภัยกัน injection ให้ต้องระวังเอง (?)
ควบคุมน้อยกว่าเต็มที่
ORM สะดวก แต่ต้องเข้าใจ SQL ข้างใต้

ORM ช่วยให้เขียนเร็วและกัน injection ให้ แต่ถ้าไม่เข้าใจ SQL ที่มันสร้างขึ้น อาจเขียนโค้ดที่ยิง query ซ้ำ ๆ จนช้าโดยไม่รู้ตัว (เช่นปัญหา N+1 query) — เรียน SQL ให้แม่นก่อน (หัวข้อก่อนหน้า) แล้ว ORM จะเป็นเครื่องทุ่นแรงที่ดี

สรุปหัวข้อนี้

  • ORM map class↔ตาราง, object↔แถว — ทำงานผ่าน Python ไม่ต้องเขียน SQL ดิบ
  • SQLAlchemy: นิยาม class, create_all, ใช้ Session ทำ CRUD
  • ORM กัน injection + เขียนเร็ว; raw SQL คุมได้เต็มที่กับ query ซับซ้อน
  • ต้องเข้าใจ SQL ข้างใต้ ไม่งั้นเสี่ยงเขียนช้า (N+1)
แบบฝึกหัด

1) นิยาม model User ด้วย SQLAlchemy แล้ว create ตาราง 2) เขียน CRUD ครบผ่าน ORM 3) แปลง CRUD ที่เขียนด้วย sqlite3 ดิบ(หัวข้อก่อน) มาเป็น ORM 4) อธิบายข้อดี/ข้อเสียของ ORM เทียบ raw SQL