Ачааллж байна...
Өмнөх хичээлд migration-ий санааг ойлгосон: бүтцийн өөрчлөлт бүрийг upgrade ба downgrade хоёр чиглэлтэй, дарааллаар холбогдсон файл болгон Git-д хадгалж, өгөгдлийн сан бүр хэддүгээр migration хүртэл хэрэгжсэнээ өөртөө тэмдэглэх. Бид тэр санааг .sql файлуудын жишээгээр дүрсэлсэн. Одоо түүнийг бодит хэрэгслээр хэрэгжүүлнэ.
Alembic бол Python-ы хамгийн өргөн хэрэглэгддэг migration хэрэгсэл. Түүнийг SQLAlchemy-г бүтээсэн хүн бүтээсэн тул SQLAlchemy болон SQLModel-тэй байгалиараа ажилладаг — Бүлэг 11-ийн engine, URL, драйвер бүгд энд ч хэрэглэгдэнэ. Энэ хичээлд бид Alembic-ийг суулгаж, migration-ий орчин үүсгэж, холболтын URL-ийг орчны хувьсагчаас уншдаг болгож, анхны migration-оо бичиж хэрэгжүүлнэ. Тэр migration-ий файлыг мөр бүрээр нь монголоор уншина — энэ бол хичээлийн гол хэсэг.
Мөн Alembic-ийн хамгийн хэрэгтэй хэдэн тушаалыг сурна: upgrade, downgrade, current, history. Хамгийн сонирхолтой нь Alembic-ийг "ажиллуулахгүйгээр" ямар SQL илгээх гэж байгааг нь харуулдаг горим — Бүлэг 1-ийн "далд байсан SQL-ийг ил гаргая" гэсэн энэ сургалтын үндсэн санаа migration-ий ертөнцөд ч хэрэглэгдэнэ.
Энэ хичээлийг бичих үед Alembic-ийн хувилбар 1.20 байсан. Таны суулгах хувилбарт үүсгэгдсэн файлууд бага зэрэг ялгаатай харагдаж болох ч бүтэц ба тушаалууд ижил.
Өмнөх хичээлд migration-ийг "дэвтрийн маягтыг албан ёсоор шинэчлэх тушаал" гэж зүйрлэсэн. Тэр зүйрлэлд тушаалуудыг бичих, дугаарлах, салбар бүрт хэрэгжүүлэх, хэддүгээр тушаал хэрэгжсэнийг бүртгэх ажлыг хэн нэгэн хийх ёстой — архивын бичиг хэргийн ажилтан. Alembic бол тэр ажилтан. Та "шинэ тушаал бэлд" гэхэд тэр загварын дагуу шинэ тушаалын хуудас бэлдэж, өмнөх тушаалтай холбож өгнө — та зөвхөн агуулгыг нь бичнэ. Та "бүх тушаалыг хэрэгжүүл" гэхэд тэр салбарын бүртгэлийг шалгаж, хэрэгжээгүйг нь л дарааллаар хэрэгжүүлж, бүртгэлийг шинэчилнэ. Та "сүүлийн тушаалыг цуцал" гэхэд тэр тушаалын хойш чиглэлийг ажиллуулна.
Migration-ий бүх замыг эхнээс нь харахын тулд хоосон өгөгдлийн сангаас эхэлнэ — library өгөгдлийн санд бидний гараар үүсгэсэн хүснэгтүүд аль хэдийн байгаа. psql-д postgres-ээр холбогдоод:
sql
CREATE DATABASE library_mig;Дараа нь PowerShell-д шинэ төслийн хавтас ба виртуал орчин:
powershell
cd $HOME\Documents\sql-course
mkdir alembic-practice
cd alembic-practice
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install alembic sqlmodel "psycopg[binary]"Энэ тушаал Alembic-ийг, SQLModel-ийг (SQLAlchemy-тай хамт), psycopg драйверийг суулгана. Мөн энэ цонхонд холболтын URL-ийг шинэ өгөгдлийн сан руу заана (өөрийн нууц үгээр):
powershell
$env:DATABASE_URL = "postgresql+psycopg://postgres:my_password@localhost:5432/library_mig"powershell
alembic init alembicЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “alembic нэртэй хавтсанд migration-ий орчин үүсгэ.” Үр дүн:
Creating directory C:\Users\...\alembic-practice\alembic ... done
Creating directory C:\Users\...\alembic-practice\alembic\versions ... done
Generating C:\Users\...\alembic-practice\alembic.ini ... done
Generating C:\Users\...\alembic-practice\alembic\env.py ... done
Generating C:\Users\...\alembic-practice\alembic\README ... done
Generating C:\Users\...\alembic-practice\alembic\script.py.mako ... done
Please edit configuration/connection/logging settings in
'C:\Users\...\alembic-practice\alembic.ini' before proceeding.Үүссэн бүтэц:
alembic-practice/
├── alembic.ini
└── alembic/
├── env.py
├── README
├── script.py.mako
└── versions/Файл бүрийн үүргийг товч танилцъя. alembic.ini — Alembic-ийн тохиргооны файл: migration-ууд хаана байрлах, лог хэрхэн хэвлэгдэх гэх мэт. Alembic тушаал бүр энэ файлыг одоогийн хавтаснаас хайдаг тул Alembic-ийн тушаалуудыг үргэлж энэ хавтаснаас ажиллуулна. alembic/env.py — Alembic тушаал бүрд ажилладаг Python скрипт: тэр engine үүсгэж, холболт нээж, transaction эхлүүлж, migration-уудыг ажиллуулдаг. Энэ файл таны төслийн нэг хэсэг бөгөөд та түүнийг засварлаж болно — доор нэг удаа засна. alembic/script.py.mako — шинэ migration файлын загвар (Mako бол загварын хэл); Alembic шинэ migration бүрийг энэ загвараас бүтээдэг. alembic/versions/ — migration файлууд энд хуримтлагдана; одоогоор хоосон.
alembic.ini-г нээвэл дунд нь ийм мөр бий:
sqlalchemy.url = driver://user:pass@localhost/dbnameAlembic-ийн анхдагч тохиргоогоор холболтын URL энд бичигдэх ёстой. Гэвч Бүлэг 11-ийн дүрэм: нууц үгтэй URL-ийг Git-д орох файлд бүү бич. alembic.ini нь migration-уудтай хамт Git-д орно. Тиймээс URL-ийг env.py дотор орчны хувьсагчаас уншдаг болгоно. alembic/env.py-г нээж, эхний хэсэгт ийм мөрүүдийг олоорой:
python
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.configТэр мөрийн яг доор хоёр мөр нэмнэ, мөн файлын хамгийн дээд хэсэгт import os нэмнэ:
python
import ospython
config = context.config
config.set_main_option("sqlalchemy.url", os.environ["DATABASE_URL"])Энэ мөр юу гэж хэлж байна вэ гэвэл: “alembic.ini-ийн sqlalchemy.url утгыг DATABASE_URL орчны хувьсагчийн утгаар соль.” env.py-ийн үлдсэн хэсэг тэр утгыг уншиж engine үүсгэдэг тул бусад зүйлийг өөрчлөх шаардлагагүй. alembic.ini-ийн driver://user:pass@... мөрийг хэвээр үлдээж болно — тэр одоо хэзээ ч хэрэглэгдэхгүй. Шударга нэг анхааруулга: хэрэв таны нууц үг % тэмдэгт агуулдаг бол энэ аргад асуудал гарч болно — Alembic-ийн тохиргоо %-ийг тусгай тэмдэгт гэж үздэг. Бүлэг 10-ын зөвлөмжийн дагуу латин үсэг, тоонуудаас бүрдсэн нууц үг энэ асуудлаас ангид.
Номын сангийн анхны хүснэгт — books — үүсгэх migration бэлдье:
powershell
alembic revision -m "create books table"Энэ тушаал юу гэж хэлж байна вэ гэвэл: “‘create books table’ гэсэн тайлбартай шинэ хоосон migration файл үүсгэ.” Үр дүн:
Generating C:\Users\...\alembic-practice\alembic\versions\3f2a1b9c8d7e_create_books_table.py ... doneФайлын нэрийн эхний хэсэг — 3f2a1b9c8d7e — нь migration-ий дугаар (revision ID). Өмнөх хичээлийн жишээнд бид 001, 002 гэх мэт энгийн дугаар ашигласан бол Alembic санамсаргүй арван хоёр тэмдэгттэй дугаар олгодог — Бүлэг 4-ийн UUID-ийн жижиг хувилбар. Шалтгаан нь хоёр хөгжүүлэгч өөр өөр компьютер дээр зэрэг migration үүсгэхэд дугаар нь мөргөлдөхгүй байх. Таны дугаар өөр байх — энэ хичээлд 3f2a1b9c8d7e-ийг гарч ирэх газар бүрт өөрийн дугаараар орлуулан уншаарай. Дугаарын араас тайлбараас үүссэн нэр.
Одоо файлыг нээж, мөр бүрээр нь уншъя:
python
"""create books table
Revision ID: 3f2a1b9c8d7e
Revises:
Create Date: 2026-10-10 21:40:12.345678
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '3f2a1b9c8d7e'
down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
pass
def downgrade() -> None:
"""Downgrade schema."""
passDocstring (эхний гурван хашилт доторх хэсэг). Хүнд зориулсан тайлбар: бидний -m-ээр өгсөн мессеж, энэ migration-ий дугаар, “Revises” — аль migration-ий дараа ирэх (хоосон — энэ эхнийх), үүсгэсэн огноо. Энэ нь Git-ийн commit мессежийн үүрэгтэй.
Import-ууд. op бол Alembic-ийн үйлдлүүдийн хэрэгслийн хайрцаг — хүснэгт үүсгэх, багана нэмэх гэх мэт. sa бол SQLAlchemy — баганын төрлүүдийг (sa.Integer, sa.Text) тайлбарлахад хэрэглэгдэнэ. typing-ийн мөр нь доорх хувьсагчдын төрлийн тайлбарт зориулагдсан — Python-ы гүнзгий түвшний сургалтад type hint-ийн тухай сурсан бол танил.
revision. Энэ migration-ий дугаар — файлын нэртэй ижил.
down_revision. Энэ migration аль migration-ий яг дараа ирэхийг заана — өмнөх хичээлийн 001, 002, 003 гэсэн дарааллын Alembic хувилбар. None нь "энэ бол хамгийн эхнийх." Дараагийн migration үүсгэхэд түүний down_revision нь '3f2a1b9c8d7e' болно — migration-ууд гинж шиг бие бие рүүгээ заана. Энэ нь Бүлэг 5-ийн FOREIGN KEY-тэй төстэй: migration бүр өмнөх рүүгээ заадаг. Alembic файлын нэрээр биш, энэ гинжээр дарааллыг тогтоодог.
branch_labels, depends_on. Нарийн төвөгтэй, олон салаатай migration-уудад зориулагдсан. Энэ сургалтад бид тэдгээрийг None хэвээр үлдээнэ.
upgrade() ба downgrade(). Өмнөх хичээлийн upgrade ба downgrade хоёр чиглэл — одоо Python функцүүд. Хоёулаа хоосон (pass) — тэдгээрийг бөглөх нь бидний ажил.
Одоо функцуудыг бөглөе. upgrade() ба downgrade()-ийг доорхоор солино:
python
def upgrade() -> None:
"""Upgrade schema."""
op.create_table(
"books",
sa.Column("id", sa.Integer, sa.Identity(always=True), primary_key=True),
sa.Column("title", sa.Text, nullable=False),
sa.Column("year", sa.Integer),
sa.Column("copies", sa.Integer, nullable=False, server_default="1"),
sa.CheckConstraint("copies >= 0", name="books_copies_check"),
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_table("books")upgrade() юу гэж хэлж байна вэ гэвэл: “books хүснэгт үүсгэ — id нь өгөгдлийн сангийн үргэлж олгодог бүхэл тоон түлхүүр, title нь хоосон байж болохгүй текст, year нь бүхэл тоо, copies нь хоосон байж болохгүй, анхдагчаар 1 байх бүхэл тоо; мөн copies сөрөг байж болохгүй гэсэн books_copies_check дүрэмтэй.” downgrade() нь: “books хүснэгтийг устга.”
Python бичлэгийг Бүлэг 10-ын SQL-тэй тааруулъя. sa.Identity(always=True) нь GENERATED ALWAYS AS IDENTITY. nullable=False нь NOT NULL. server_default="1" нь DEFAULT 1 — “server” гэдэг үг нь анхдагч утгыг Python биш, өгөгдлийн сан өөрөө хэрэгжүүлнэ гэсэн утгатай (Бүлэг 4-ийн DEFAULT). sa.CheckConstraint(...) нь Бүлэг 4-ийн CHECK, нэртэйгээр — Бүлэг 4-т “CHECK-д нэр өгөх нь сайн дадал” гэж сурсан бөгөөд migration-д нэр бүр чухал, учир нь хожим тэр дүрмийг өөрчлөх migration түүнийг нэрээр нь олох ёстой. Alembic-ийн op ба SQLAlchemy-ийн sa хэрэгслүүд таны мэдэх SQL-ийн Python хувилбар л юм.
Жишээ 1: migration-ийг хэрэгжүүлэх
powershell
alembic upgrade headЭнэ тушаал юу гэж хэлж байна вэ гэвэл: "өгөгдлийн санг хамгийн сүүлийн migration (head) хүртэл шинэчил." Үр дүн:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 3f2a1b9c8d7e, create books tableМөр бүрийг уншъя. Эхний мөр: “PostgreSQL-ийн хэрэгжүүлэлтийг ашиглана.” Хоёр дахь мөр: "бүтцийн өөрчлөлт transaction-д багтана гэж үзнэ" — өмнөх хичээлийн Жишээ 4-ийн PostgreSQL-ийн чадвар. Alembic migration бүрийг transaction-д ажиллуулна: алдаа гарвал бүгд цуцлагдана. Гурав дахь мөр: "хоосон байдлаас 3f2a1b9c8d7e хүртэл upgrade ажиллуулж байна, ‘create books table’." Сумны зүүн тал хоосон — өгөгдлийн сан ямар ч migration хэрэгжүүлээгүй байсан.
psql-ээр шалгая (psql -U postgres -d library_mig):
library_mig=# \dt
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------
public | alembic_version | table | postgres
public | books | table | postgres
(2 rows)Хоёр хүснэгт. books бол бидний migration-ий үүсгэсэн хүснэгт. alembic_version бол Alembic өөрөө үүсгэсэн — өмнөх хичээлийн Жишээ 3-ын "өгөгдлийн сан өөрийн хувилбарыг мэддэг" хүснэгт:
sql
SELECT * FROM alembic_version; version_num
--------------
3f2a1b9c8d7e
(1 row)Энэ query юу гэж хэлж байна вэ гэвэл: "энэ өгөгдлийн санд хэрэгжсэн хамгийн сүүлийн migration-ий дугаарыг харуул." Зүйрлэлийн "бид хэддүгээр тушаал хүртэл хэрэгжүүлсэн" бүртгэл. \d books ажиллуулбал id баганын хажууд generated always as identity, copies-ийн хажууд default 1, доор нь books_copies_check дүрэм — Python-оор бичсэн бүх зүйл SQL болж хэрэгжсэн.
Жишээ 2: current ба history
Alembic-ээс өгөгдлийн сангийн одоогийн байдлыг асууя:
powershell
alembic currentINFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
3f2a1b9c8d7e (head)Энэ хариу юу гэж хэлж байна вэ гэвэл: "энэ өгөгдлийн сан 3f2a1b9c8d7e migration дээр байна, энэ нь хамгийн сүүлийнх (head)." Alembic alembic_version хүснэгтийг уншиж, файлуудын гинжтэй харьцуулсан. Хэрэв өгөгдлийн сан хоцорсон бол (head) тэмдэг гарахгүй — тэр нь "шинэчлэх хэрэгтэй" гэсэн дохио.
powershell
alembic history<base> -> 3f2a1b9c8d7e (head), create books tableЭнэ хариу юу гэж хэлж байна вэ гэвэл: “migration-уудын түүх: эхлэлээс (base) 3f2a1b9c8d7e хүртэл, ‘create books table’.” history нь өгөгдлийн сан биш, файлуудыг уншдаг — migration-уудын гинжийг харуулна. Дараагийн хичээлд хоёр дахь migration нэмэхэд энэ гинж урт болно. history нь Git-ийн log-тэй адил: бүтэц ямар өөрчлөлтүүдийг туулсныг нэг дор харуулдаг — өмнөх хичээлийн "түүх байхгүй" асуудлын шийдэл.
Жишээ 3: downgrade ба дахин upgrade
Migration-ийн хойш чиглэлийг туршъя:
powershell
alembic downgrade -1Энэ тушаал юу гэж хэлж байна вэ гэвэл: "одоогийн байдлаас нэг migration-ээр буцаа." Үр дүн:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running downgrade 3f2a1b9c8d7e -> , create books tableСум одоо эсрэг чиглэлтэй: 3f2a1b9c8d7e-ээс хоосон байдал руу. Alembic downgrade() функцийг ажиллуулж, books хүснэгтийг устгасан. psql-д \dt хийвэл зөвхөн alembic_version үлдсэн, SELECT * FROM alembic_version; нь хоосон — өгөгдлийн сан эхлэл байдалдаа буцсан.
Дахин урагш:
powershell
alembic upgrade headbooks хүснэгт дахин үүснэ. Энэ туршилт нь migration-ий хоёр чиглэл хоёулаа ажиллаж байгааг баталгаажуулдаг — бодит төслүүдэд migration бичсэний дараа upgrade, downgrade, дахин upgrade гэсэн гурван алхмыг өөрийн компьютер дээр туршиж үзэх нь сайн дадал. Downgrade ажиллахгүй migration нь асуудал гарсан өдөр таныг аврахгүй. Өмнөх хичээлийн анхааруулга энд ч хүчинтэй: books хүснэгтэд өгөгдөл байсан бол downgrade түүнийг бүрмөсөн устгах байсан.
Жишээ 4: ажиллуулахгүйгээр SQL-ийг харах
Alembic Python-оор бичсэн migration-ийг SQL болгон хувиргаж илгээдэг — SQLModel-ийн нэгэн адил орчуулагч. Тэр орчуулгыг өгөгдлийн санд хүргэлгүйгээр харах арга бий:
powershell
alembic upgrade head --sqlЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “head хүртэлх upgrade-ийг ажиллуулалгүйгээр, илгээх байсан SQL-ийг хэвлэ.” Үр дүн (товчилсон):
sql
BEGIN;
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL,
CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
);
-- Running upgrade -> 3f2a1b9c8d7e
CREATE TABLE books (
id INTEGER GENERATED ALWAYS AS IDENTITY,
title TEXT NOT NULL,
year INTEGER,
copies INTEGER DEFAULT '1' NOT NULL,
PRIMARY KEY (id),
CONSTRAINT books_copies_check CHECK (copies >= 0)
);
INSERT INTO alembic_version (version_num) VALUES ('3f2a1b9c8d7e') RETURNING alembic_version.version_num;
COMMIT;Энэ гаралтыг уншаад Бүлэг 1-ийн анхны хичээлийн зураглалыг санаарай: нэг талд Python, нөгөө талд SQL. Энд бүх зүйл танил: BEGIN ба COMMIT — Бүлэг 12-ын transaction, migration бүхэлдээ нэг гэрээ. alembic_version-ийг үүсгэх CREATE TABLE. Бидний бичсэн op.create_table-ийн SQL хувилбар — Бүлэг 10-ын library_pg.sql-тэй бараг ижил. Эцэст нь alembic_version хүснэгтэд шинэ дугаарыг бичих INSERT — Бүлэг 11-ийн RETURNING-тэй. Энэ горим хоёр зүйлд хэрэгтэй. Нэгдүгээрт, migration яг юу хийх гэж байгааг шалгах — ялангуяа жинхэнэ server дээр ажиллуулахын өмнө. Хоёрдугаарт, зарим байгууллагад өгөгдлийн сангийн администратор migration-ийг Python-оор биш, SQL файл хэлбэрээр хүлээн авч, өөрөө хянаж ажиллуулдаг — энэ горим тэр файлыг бэлддэг.
Жишээ 5: Git-д хадгалах
Migration-ий бүх утга нь Git-д кодтой хамт хадгалагдахад оршино. "Хөгжүүлэгчийн хэрэгсэл" сургалтын дадлаар alembic-practice хавтсанд git init хийж, .gitignore файлд .venv/ болон __pycache__/ нэмээд, git add alembic.ini alembic ба git commit -m "Add Alembic environment and books table migration" хийнэ. alembic.ini ба alembic/ хавтас (env.py, versions доторх migration файлууд) бүгд commit-д орно — нууц үг аль ч файлд байхгүй, учир нь тэр зөвхөн орчны хувьсагчид амьдарна. Багийн гишүүн энэ repository-г татаж аваад, өөрийн DATABASE_URL-ийг тохируулж, alembic upgrade head ажиллуулахад яг ижил books хүснэгттэй болно.
Alembic-д alembic revision --autogenerate -m "..." гэсэн хүчирхэг сонголт бий: тэр таны SQLModel/SQLAlchemy загваруудыг өгөгдлийн сангийн одоогийн бүтэцтэй харьцуулж, ялгааг migration болгон автоматаар бичдэг. Энэ нь бодит төслүүдэд маш өргөн хэрэглэгддэг бөгөөд их цаг хэмнэдэг. Энэ сургалтад бид migration-уудыг гараар бичиж байгаа нь санаатай: Бүлэг 1-ээс хойш бидний дадал "орчуулагч юу хэлж байгааг ойлгох" байсан, мөн autogenerate-ийн бичсэн migration-ийг хянахын тулд та migration-ийг гараар бичих чадвартай байх ёстой. Autogenerate бүх зүйлийг илрүүлдэггүй — жишээ нь баганын нэр солихыг "нэг баганыг устгаад шинийг нэмэх" гэж ойлгож, өгөгдлийг устгах migration бичиж болно. Тиймээс мэргэжлийн дүрэм: autogenerate-ийн үүсгэсэн migration бүрийг уншиж, засаж, туршсаны дараа л хэрэгжүүл.
Хэрэв сонирхож байвал хоёр дахь migration үүсгэж (alembic revision -m "create members table"), шинэ файлын down_revision нь эхний migration-ий дугаар руу автоматаар заасныг шалгаарай. members хүснэгтийг (id, name, email UNIQUE) бичээд, alembic upgrade head, alembic history, alembic downgrade -1, alembic current гэсэн дарааллыг ажиллуулж, хариу бүрийг уншаарай. Дараагийн хичээл books дээр ажиллах тул туршилтын дараа members-ийн migration файлыг устгахаасаа өмнө alembic downgrade -1 хийхээ мартуузай — эс бөгөөс alembic_version байхгүй файл руу заана. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Буруу хавтаснаас ажиллуулах. alembic.ini байхгүй хавтаснаас Alembic-ийн тушаал ажиллуулбал FAILED: No config file 'alembic.ini' found, or file has no '[alembic]' section гарна. Энэ мессеж юу гэж хэлж байна вэ гэвэл: “alembic.ini тохиргооны файл олдсонгүй, эсвэл [alembic] хэсэггүй байна.” cd $HOME\Documents\sql-course\alembic-practice хий.
Орчны хувьсагч тогтоогоогүй. Шинэ PowerShell цонхонд $env:DATABASE_URL тогтоолгүйгээр alembic upgrade head ажиллуулбал traceback-ийн төгсгөлд KeyError: 'DATABASE_URL' гарна — env.py дахь бидний нэмсэн мөрөөс. Бүлэг 11-ийн танил алдаа: Алхам 1-ийн мөрийг энэ цонхонд дахин ажиллуул.
'alembic' is not recognized. Виртуал орчин идэвхгүй бол PowerShell alembic : The term 'alembic' is not recognized... гэнэ. .venv\Scripts\Activate.ps1 хий.
Хүснэгт аль хэдийн байх. Хэрэв books хүснэгтийг psql-ээр гараар үүсгэсэн өгөгдлийн санд migration хэрэгжүүлбэл:
sqlalchemy.exc.ProgrammingError: (psycopg.errors.DuplicateTable) relation "books" already existsЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “books relation аль хэдийн байна.” Өмнөх хичээлийн "гараар хийсэн өөрчлөлтөөс үүссэн зөрүү"-ийн бодит хувилбар. Migration transaction-д ажилласан тул юу ч өөрчлөгдөөгүй, alembic_version шинэчлэгдээгүй. Энэ хичээлд бид хоосон library_mig өгөгдлийн сан үүсгэсэн нь яг энэ шалтгаантай.
Migration файл дахь Python алдаа. upgrade() функцэд үсгийн алдаа (op.create_tabel) байвал AttributeError гарна — Alembic migration-ийг ажиллуулж эхэлсэн тул transaction-ийг цуцлах бөгөөд өгөгдлийн сан хөндөгдөхгүй. Файлыг засаад дахин ажиллуул. Энэ нь хэрэгжээгүй migration — хэрэгжсэн migration-ийг засахгүй гэсэн өмнөх хичээлийн дүрэм энд хамаарахгүй.
Энэ хичээлд та Alembic-ээр migration-ий санааг хэрэгжүүллээ. alembic init alembic нь alembic.ini тохиргоо, Alembic тушаал бүрд ажилладаг env.py, шинэ migration-ий загвар, versions/ хавтас бүхий орчин үүсгэдэг; бид env.py-д нэг мөр нэмж холболтын URL-ийг орчны хувьсагчаас уншдаг болгосон. alembic revision -m "..." нь дугаартай хоосон migration үүсгэдэг; файлын revision ба down_revision нь migration-уудыг гинж болгон холбож дарааллыг тогтоодог, upgrade() ба downgrade()-ийг бид op.create_table, op.drop_table зэрэг SQL-ийн Python хувилбараар бөглөнө. alembic upgrade head migration-уудыг transaction-д хэрэгжүүлж, alembic_version хүснэгтэд дугаарыг тэмдэглэдэг; current, history, downgrade -1 нь байдал, түүх, буцаалтыг удирддаг; --sql нь илгээх SQL-ийг ажиллуулахгүйгээр харуулдаг. Migration орчныг кодтой хамт Git-д хадгална. Autogenerate хүчирхэг ч түүний бичсэн migration бүрийг хянах хэрэгтэй.
Дараагийн хичээлд бодит өөрчлөлтийг эхнээс дуустал хийнэ: өгөгдөлтэй books хүснэгтэд rating багана нэмэх migration бичиж, хэрэгжүүлж, буцааж, дахин хэрэгжүүлж, түүхийг харна. Мөн өгөгдөлтэй хүснэгтэд NOT NULL багана нэмэх нь яагаад хоосон хүснэгттэй харьцуулахад илүү болгоомжтой migration шаарддагийг харна.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.