Ачааллж байна...
"Өгөгдлийн сан ба SQL" сургалтад тавтай морилно уу. Хэрэв та “FastAPI — Вэб API бүтээх” сургалтыг дүүргэсэн бол Тэмдэглэлийн API болон Номын сангийн API-г өөрийн гараар бүтээсэн. Тэдгээр API өгөгдөл хадгалдаг, хадгалсан өгөгдлөө буцааж уншдаг, засдаг, устгадаг байсан. Өөрөөр хэлбэл та өгөгдлийн сантай ажилладаг жинхэнэ програм бичсэн. Энэ бол жижиг амжилт биш бөгөөд энэ сургалт тэр амжилт дээрээ шууд үргэлжилнэ.
Гэхдээ олон суралцагч яг энэ үед нэг мэдрэмж төрдөг: "миний код ажилладаг, гэхдээ доор нь юу болдогийг би мэдэхгүй." session.add() гэж бичихэд өгөгдөл хаа нэгтээ хадгалагддаг. select(Book) гэж бичихэд номнууд буцаж ирдэг. Гэвч тэр хооронд яг юу болсныг та хараагүй. Хэрэв та ийм мэдрэмжтэй байгаа бол энэ нь таны алдаа биш, харин FastAPI сургалтын санаатай шийдвэр байсан гэдгийг эхлээд хэлье.
FastAPI сургалт SQLModel ашиглан өгөгдлийн сангийн нарийн ширийнийг зориуд нуусан. Тэр үед гол зорилго нь API бүтээх — route, request, response, validation-ийг ойлгох байсан. Хэрэв тэр үед SQL хэл, schema зохион байгуулалт, JOIN зэргийг нэгэн зэрэг заасан бол хэт олон шинэ зүйл нэг дор ирж, аль нь ч бүрэн ойлгогдохгүй байх байсан. Тиймээс SQLModel нь дугуйн туслах дугуй шиг үүрэг гүйцэтгэсэн: тэнцвэрээ олох хүртэл таныг унахаас хамгаалсан. Одоо та тэнцвэрээ олсон тул туслах дугуйг авах цаг болжээ.
Энэ сургалтын төгсгөлд та SQL хэлээр өөрөө query бичдэг, хүснэгтүүдээ зөв зохион байгуулдаг, олон хүснэгтийг JOIN-оор холбож уншдаг, тоо баримтыг нэгтгэн тайлан гаргадаг болно. Үүнээс гадна PostgreSQL гэдэг мэргэжлийн өгөгдлийн сантай ажиллаж, transaction ба migration гэх мэт жинхэнэ ажлын дадлыг эзэмшинэ. Хамгийн сүүлд FastAPI сургалтын Номын сангийн API-гаа PostgreSQL руу шилжүүлнэ. Өөрөөр хэлбэл таны аль хэдийн бүтээсэн зүйл энэ сургалтын материал болж, шинэ нүдээр дахин харагдана.
SQLModel-ийг орчуулагчтай зүйрлэж болно. Та Python хэлээр ярьдаг, харин өгөгдлийн сан зөвхөн SQL хэлийг ойлгодог. Энэ хоёрын дунд SQLModel орчуулагч болж зогсдог: та Python-оор “2000 оноос хойш гарсан номнуудыг өгөөч” гэж хэлэхэд тэр үүнийг SQL руу орчуулж өгөгдлийн санд дамжуулдаг. Өгөгдлийн сан хариу өгөхөд орчуулагч дахин Python руу буцааж орчуулна. Энэ бол маш сайн орчуулагч бөгөөд ихэнх тохиолдолд алдаагүй ажилладаг.
Гэхдээ орчуулагчаар дамжиж ярихын нэг сул тал бий: та яриаг өөрөө хэзээ ч сонсдоггүй. Хэрэв нэг өдөр хариу удаан ирвэл, эсвэл ойлгомжгүй алдаа гарвал та юу буруу болсныг мэдэх аргагүй. Учир нь асуудал таны хэлсэн үгэнд байна уу, орчуулгад байна уу, эсвэл өгөгдлийн сангийн өөрт нь байна уу гэдгийг ялгах хэлний мэдлэг танд байхгүй. Гадаад оронд орчуулагчтай явж байгаад орчуулагчаа түр холдоход гацдаг хүнийг төсөөлөөд үзээрэй.
Энэ сургалт танд тэр хэлийг өөрөө сургана. Орчуулагч ажлаа үргэлжлүүлэн хийсээр байх болно — мэргэжлийн хөгжүүлэгчид ч SQLModel, SQLAlchemy зэрэг хэрэгслийг өдөр бүр ашигладаг. Ялгаа нь гэвэл та одоо орчуулагчийн юу хэлж байгааг сонсож, шаардлагатай үед өөрөө шууд ярьж чаддаг болно. FastAPI сургалтад бид хүснэгтийг бүртгэлийн дэвтэртэй зүйрлэсэн; энэ сургалтад тэр дэвтрийг өөрийн гараар нээж, мөр бүрийг нь уншиж сурна.
Энэ сургалтын гол санааг нэг зураглалаар харуулъя. Номын сангийн API-д ойролцоогоор иймэрхүү Python мөр байсан:
python
books = session.exec(select(Book).where(Book.year > 2000)).all()Энэ мөрийг уншвал: select(Book) нь “Book загварын мөрүүдийг сонго” гэсэн утгатай, .where(Book.year > 2000) нь "зөвхөн year нь 2000-аас их байгааг" гэсэн нөхцөл нэмж байна, session.exec(...) нь энэ хүсэлтийг өгөгдлийн сан руу илгээж, .all() нь ирсэн бүх үр дүнг жагсаалт болгон авч байна. Та энэ мөрийг бичихдээ Python-оор бодож байсан бөгөөд энэ нь зөв байсан.
Харин SQLModel энэ мөрийг өгөгдлийн сан руу илгээхээсээ өмнө дараах SQL болгон хувиргадаг:
sql
SELECT book.id, book.title, book.author, book.year
FROM book
WHERE book.year > ?Энэ query юу гэж хэлж байна вэ гэвэл: “book хүснэгтээс id, title, author, year гэсэн дөрвөн баганыг ав, гэхдээ зөвхөн year нь өгсөн утгаас их мөрүүдийг.” Анзаарвал SQL нь бараг энгийн англи өгүүлбэр шиг уншигддаг: SELECT — сонго, FROM — хаанаас, WHERE — ямар нөхцөлтэй. Энэ сургалтад SQL-ийн түлхүүр үгсийг (SELECT, FROM, WHERE гэх мэт) үргэлж том үсгээр бичнэ. Энэ нь SQL заавал шаарддаг дүрэм биш ч түлхүүр үгийг хүснэгт ба баганын нэрээс ялгаж харахад тусалдаг уламжлал юм.
Сүүлийн мөрөнд байгаа ? тэмдэгт нь сонирхолтой. Энэ нь "энд нэг утга орно" гэсэн орлуулагч бөгөөд 2000 гэсэн тоо query-ний текстэд шууд бичигддэггүй, харин тусад нь илгээгддэг. Яагаад ингэдгийг Бүлэг 11-д SQL injection гэдэг аюулын тухай ярихдаа нарийн тайлбарлана. Одоохондоо зөвхөн нэг зүйлийг анзаарахад хангалттай: таны нэг мөр Python код өгөгдлийн сан дээр бүтэн SQL өгүүлбэр болж очдог байсан. Энэ сургалт тэр өгүүлбэрүүдийг ил гаргаж, уншиж, өөрөө бичиж сургана.
Дээрх жишээ ганцаараа биш. FastAPI сургалтад бүтээсэн API-дээ та өгөгдлийн сантай холбоотой юу ч хийсэн бай, ар талд нь SQL ажиллаж байсан. Эхний жишээ бол програм эхлэх үе юм. Та SQLModel.metadata.create_all(engine) гэсэн мөр бичиж, хүснэгтүүд автоматаар үүсдэг байсныг санаж байгаа байх. Тэр мөр ар талдаа CREATE TABLE гэсэн SQL тушаал илгээж, хүснэгт бүрийн нэр, багана, төрлийг өгөгдлийн санд зарладаг байсан. Бүлэг 4-т та тэр тушаалыг өөрийн гараар бичиж, багана бүрд ямар дүрэм тавьж болохыг сурна.
Хоёр дахь жишээ бол шинэ тэмдэглэл нэмэх үе. Тэмдэглэлийн API-д POST /notes хүсэлт ирэхэд та session.add(note) болон session.commit() гэж бичдэг байсан. Энэ хоёр мөр нийлээд INSERT INTO гэсэн SQL тушаал болж, хүснэгтэд шинэ мөр нэмдэг байсан. Тэр commit гэдэг үг ч санамсаргүй биш — энэ нь өгөгдлийн сангийн transaction гэдэг ойлголттой шууд холбоотой бөгөөд Бүлэг 12-т бид түүний цаад утгыг бүрэн нээнэ. Өөрөөр хэлбэл та transaction-ийг аль хэдийн ашиглаж байсан, зөвхөн нэрийг нь мэдээгүй байсан.
Гурав дахь жишээ бол нэг зүйлийг ID-аар нь олох эсвэл устгах үе. session.get(Book, book_id) гэж бичихэд SQLModel нь SELECT ... WHERE id = ? хэлбэрийн query илгээдэг байсан, харин устгах endpoint дээр session.delete(book) нь DELETE FROM тушаал болдог байсан. Энд нэг чухал зүйл бий: DELETE тушаалд WHERE нөхцөл байхгүй бол хүснэгтийн бүх мөр устдаг. SQLModel таныг ийм алдаанаас хамгаалж байсан ч SQL-ийг шууд бичих үед энэ хамгаалалт байхгүй. Бүлэг 3-т бид энэ аюулыг хаях хуулбар дээр зориуд үзүүлж, түүнээс хамгаалах дадлыг сурна.
Эдгээр гурван жишээнээс нэг дүгнэлт гарна: таны API-ийн endpoint бүр өгөгдлийн сантай хийсэн жижиг яриа байсан. Та Python-оор ярьж, SQLModel орчуулж, өгөгдлийн сан SQL-ээр хариулж байсан. Энэ сургалтын эхний гурван түвшинд бид орчуулагчийг түр хойш тавьж, өгөгдлийн сантай шууд SQL-ээр ярина. Дараа нь Түвшин 5-д орчуулагч руугаа буцаж очихдоо та түүний хийж буй бүх зүйлийг ойлгож, хэзээ түүнд итгэх, хэзээ өөрөө шууд ярихыг шийддэг болсон байна.
Энэ сургалт таван түвшинтэй бөгөөд зам нь санаатайгаар ингэж зохион байгуулагдсан:
Түвшин 1: SQL хэлтэй нүүр тулах — өгөгдөл унших, шүүх, эрэмбэлэх, нэмэх, засах, устгах
Түвшин 2: Schema зохион байгуулалт — хүснэгт зохиох, дүрэм тавих, хүснэгтүүдийг холбох
Түвшин 3: Хүчирхэг query — JOIN, aggregate, GROUP BY, subquery, index
Түвшин 4: PostgreSQL — мэргэжлийн өгөгдлийн сан руу шилжиж, Python-оос холбогдох, transaction
Түвшин 5: Мэргэжлийн дадал — migration, ORM-ийн гүнзгий ойлголт, төгсгөлийн төсөл
Эхний гурван түвшинд бид SQLite ашиглана. SQLite бол нэг файл дотор амьдардаг өгөгдлийн сан бөгөөд ямар ч server суулгах шаардлагагүй. Үүнийг хувийн дэвтэртэй зүйрлэж болно: та түүнийг өөрийн ширээн дээр нээж, хүссэн үедээ бичдэг. Бид DB Browser for SQLite гэдэг энгийн програм ашиглаж, query-гээ бичээд үр дүнг нь хүснэгт хэлбэрээр шууд харах болно. Ингэснээр та SQL хэлээ сурахдаа server тохируулах, нууц үг санах зэрэг нэмэлт ачаалалгүйгээр зөвхөн хэл дээрээ анхаарлаа төвлөрүүлнэ.
Түвшин 4-т SQL танд айдас төрүүлэхээ больсон үед бид PostgreSQL руу шилжинэ. PostgreSQL нь архивын албатай төстэй: тусдаа ажилладаг, олон хүнд нэгэн зэрэг үйлчилдэг, дүрэм журам нь илүү хатуу. Олон томоохон компани, вэб сайт PostgreSQL дээр ажилладаг. Гэхдээ тэнд хүрэх үед таны мэдэх SQL бараг бүхэлдээ хэвээр ажиллах тул энэ шилжилт шинэ хэл сурах биш, харин мэддэг хэлээрээ шинэ газар ярих мэт санагдана.
Энэ сургалт өмнөх сургалтуудын адил дүрэмтэй. Шалгалт, тест, гэрийн даалгавар байхгүй — бүх хичээлийг дүүргэхэд гэрчилгээ авна. Та өөрийн хурдаар явна. Хичээлүүдэд "Туршаад үзээрэй" хэсэг байх боловч тэдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж хэзээ ч тооцохгүй. Мөн энэ сургалтад нэг онцгой дадал бий: query бүрийг задлан шинжлэхээсээ өмнө монгол хэлээр чангаар уншина. Дээрх жишээн дээр "энэ query юу гэж хэлж байна вэ гэвэл" гэж уншсан шиг. Query бүрийн өмнө ба дараах өгөгдлийг жижиг хүснэгтээр харуулах тул мөр бүрт юу тохиолдсоныг та өөрийн нүдээр мөшгиж чадна.
Хэрэв FastAPI сургалтын Номын сангийн API төсөл тань компьютерт хадгалагдсан хэвээр байвал нэг сонирхолтой зүйл туршиж болно. create_engine(...) гэж бичсэн мөрийг олоод, хаалтан дотор нь echo=True гэж нэмээрэй (аль хэдийн байгаа бол зүгээр). Дараа нь сервероо асааж, /docs хуудаснаас хэд хэдэн endpoint дуудаад терминал руугаа хараарай. Таны хүсэлт бүрийн араас SQL тушаалууд урсаж гарч ирэхийг харах болно.
Одоохондоо тэдгээрийг бүрэн ойлгох шаардлагагүй. Зүгээр л SELECT, INSERT, WHERE гэх мэт үгс хаана гарч ирж байгааг анзаараад, "аа, энэ бол миний сая дуудсан endpoint-ийн яриа" гэж мэдрэхэд хангалттай. Хэрэв төсөл тань байхгүй эсвэл одоо туршихыг хүсэхгүй бол огт хамаагүй — дараагийн хичээлүүд үүнийг хийсэн гэж тооцохгүй.
Энэ хичээлд код ажиллуулаагүй тул алдааны мессеж байхгүй. Харин энэ сургалтыг эхлэх үед олон хүнд төрдөг гурван буруу ойлголт бий. Эхнийх нь “ORM байгаа болохоор SQL сурах шаардлагагүй” гэсэн бодол. ORM гэдэг нь SQLModel, SQLAlchemy зэрэг Python объектыг өгөгдлийн сангийн хүснэгттэй холбодог хэрэгслийн ерөнхий нэр юм. ORM нь өдөр тутмын энгийн ажлыг хурдасгадаг ч програм удаашрах, хачин алдаа гарах үед асуудлыг олох цорын ганц арга нь ар талд нь юу болж байгааг SQL-ээр унших юм. Бүлэг 14-т та ORM-ийн хийж буй нэг нууц алдааг (N+1 асуудал) өөрийн нүдээр харах бөгөөд SQL мэдэхгүйгээр түүнийг олох боломжгүй.
Хоёр дахь буруу ойлголт бол “SQL бол Python шиг дахин нэг програмчлалын хэл тул маш хэцүү байх” гэсэн айдас. Үнэндээ SQL нь Python-оос өөр төрлийн хэл. Python-д та компьютерт яаж хийхийг алхам алхмаар заадаг бол SQL-д юу хүсэж байгаагаа л хэлдэг, харин яаж олохыг өгөгдлийн сан өөрөө шийддэг. “2000 оноос хойш гарсан номнуудыг өг” гэж хэлэхэд та давталт бичих, нөхцөл шалгах шаардлагагүй. Тиймээс эхний query-нүүд тань гайхмаар богино, ойлгомжтой байх болно.
Гурав дахь буруу ойлголт бол “SQLite бол тоглоом, жинхэнэ ажилд хэрэглэдэггүй” гэсэн бодол. SQLite нь ухаалаг утас, вэб хөтөч болон олон мянган програмын дотор ажиллаж байдаг, дэлхийд хамгийн өргөн тархсан өгөгдлийн сангуудын нэг юм. Түүний зорилго PostgreSQL-ээс өөр — нэг програм, нэг хэрэглэгчид зориулсан хувийн дэвтэр. Бид SQLite-ээр эхлэх нь хялбар учраас бус, харин SQL хэлийг хамгийн цэвэр орчинд сурах боломж олгодог учраас юм.
Энэ хичээлд та FastAPI сургалтад SQLModel-ийн ард нуугдаж байсан SQL-тэй анх удаа нүүр тулж уулзлаа. Таны бичсэн нэг Python мөр өгөгдлийн сан дээр бүтэн SQL өгүүлбэр болж очдог байсныг, мөн хүснэгт үүсгэх, мөр нэмэх, хайх, устгах бүрт өөр өөр SQL тушаал ажиллаж байсныг харлаа. Энэ сургалт SQLite болон DB Browser for SQLite-ээр эхэлж, SQL хэлийг server тохиргоогүйгээр сургаад, дараа нь PostgreSQL руу шилжинэ. Шалгалт, гэрийн даалгавар байхгүй, та өөрийн хурдаар явна.
Дараагийн хичээлд бид DB Browser for SQLite програмыг компьютертээ суулгаж, интерфейстэй нь танилцана. Мөн энэ сургалтын турш ашиглах жижиг жишээ өгөгдлийн санг өөрсдөө үүсгэнэ. Тэгснээр Хичээл 3-т анхны SELECT query-гээ бичих бүх зүйл бэлэн болно.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.