Ачааллж байна...
Энэ бол сургалтын төгсгөлийн ажлын эхний хагас. Арван дөрвөн бүлгийн туршид та SELECT-ээс эхлээд migration хүртэл нэг нэгээр нь сурсан. Одоо тэдгээрийг тусдаа дасгал болгон биш, нэг бүтэн ажил болгон хийнэ — бодит төсөлд хийдэг дарааллаар нь.
Бид шинэ, хоосон library_final өгөгдлийн санд Номын сангийн бүтэн системийг эхнээс бүтээнэ. Энэ удаа schema-г library_pg.sql гэх мэт нэг скриптээр биш, Бүлэг 13-ын аргаар — дугаарлагдсан migration-уудаар — бүтээнэ, ингэснээр бүтэц эхний өдрөөсөө түүхтэй, буцаагдах боломжтой байна. Дараа нь сургалтын туршид хэрэглэсэн найман номтой жижиг өгөгдлийн оронд бодит хэмжээний өгөгдөл — хоёр мянган гишүүн, таван зуун ном, гучин мянган зээл — үүсгэнэ, учир нь Бүлэг 9-ийн index ба Бүлэг 14-ийн N+1 хичээлүүд зөвхөн том өгөгдөл дээр л үнэн царайгаа харуулдгийг бид мэднэ. Эцэст нь бүх зүйлийг backup хийж, тэр backup үнэхээр сэргээгддэгийг шалгана.
Дараагийн хичээлд энэ өгөгдлийн сан дээр тайлангуудыг бичиж, хэмжиж, index-ээр хурдасгаж, транзакцтай зээл олгох үйлдлийг Python-оор бичнэ. Энэ хичээл түүний суурь.
Байшин барих гурван үе шатыг төсөөлөөрэй. Эхлээд зураг төсөл: хана, хаалга, цонх хаана байхыг дугаарласан зургууд — ямар дарааллаар баригдсаныг хэн ч харж болно, буруу бол засна. Дараа нь тавилга: хүн амьдрахад хэрэгтэй бүх зүйл — гэхдээ тавилга зураг төсөлд ордоггүй, тусдаа хөдлөх юм. Эцэст нь даатгал: гал гарвал байшинг сэргээх баталгаа, гэхдээ даатгалын гэрээг гаргасан гэдэг нь сэргээж чадна гэсэн үг биш — нэхэмжлэл үнэхээр төлөгддөг эсэхийг урьдчилан мэдэх нь чухал. Энэ хичээлд бүтэц бол migration (зураг төсөл), өгөгдөл бол seed (тавилга), backup бол даатгал — мөн бид нэхэмжлэлийг туршиж үзнэ.
Documents\sql-course дотор шинэ хавтас capstone үүсгэж, PowerShell-д:
powershell
cd $HOME\Documents\sql-course\capstone
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install alembic sqlmodel "psycopg[binary]"Өгөгдлийн сан үүсгэж, холболтын хаягийг тохируулна (кирилл тохиргоо — chcp 65001, $env:PGCLIENTENCODING="UTF8" — аль хэдийн хийгдсэн гэж үзье):
powershell
psql -U postgres -c "CREATE DATABASE library_final"
$env:DATABASE_URL = "postgresql+psycopg://postgres:PASSWORD@localhost:5432/library_final"
alembic init alembicБүлэг 13-ын Alembic үндэс хичээлийн нэгэн адил alembic/env.py-ийг DATABASE_URL-ээс уншдаг болгоно — config = context.config мөрийн доор:
python
import os
config.set_main_option("sqlalchemy.url", os.environ["DATABASE_URL"])Эцэст нь Git:
powershell
git init.gitignore файл (VS Code-оор):
.venv/
__pycache__/
*.dump*.dump мөрийг анзаараарай — Алхам 6-д тайлбарлана.
Бүтцийг гурван логик алхамд хуваана — Бүлэг 5-ын "эцэг эхийг эхэлж, хүүхдийг дараа нь" дүрмээр: заалт хийдэг хүснэгтүүд заагдаж буй хүснэгтүүдээсээ хойш үүснэ.
Migration 1: гишүүд ба зохиогчид
powershell
alembic revision -m "create members and authors"Үүссэн файлын функцууд:
python
def upgrade() -> None:
"""Upgrade schema."""
op.create_table(
"members",
sa.Column("id", sa.Integer, sa.Identity(always=True), primary_key=True),
sa.Column("name", sa.Text, nullable=False),
sa.Column("email", sa.Text, unique=True),
sa.Column("city", sa.Text),
sa.Column("joined_on", sa.Date, nullable=False, server_default=sa.text("CURRENT_DATE")),
sa.Column("is_active", sa.Boolean, nullable=False, server_default=sa.true()),
)
op.create_table(
"authors",
sa.Column("id", sa.Integer, sa.Identity(always=True), primary_key=True),
sa.Column("name", sa.Text, nullable=False),
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_table("authors")
op.drop_table("members")Энэ бол Бүлэг 10-ын library_pg.sql-ийн members ба authors — Python-оор. sa.Identity(always=True) — Бүлэг 4-ийн GENERATED ALWAYS AS IDENTITY. unique=True — UNIQUE; PostgreSQL түүнд members_email_key гэсэн нэр автоматаар өгнө. server_default нь Бүлэг 4-ийн DEFAULT: “server талд” гэдэг нь утгыг Python биш, PostgreSQL өөрөө бөглөнө гэсэн үг — тиймээс psql-ээс INSERT хийсэн ч ажиллана. sa.text("CURRENT_DATE") нь "энэ бол текст биш, SQL илэрхийлэл" гэж Alembic-д хэлдэг; хашилтгүйгээр 'CURRENT_DATE' гэсэн тэмдэгт мөр болох байсан.
Migration 2: номнууд
powershell
alembic revision -m "create books"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("genre", sa.Text),
sa.Column("copies", sa.Integer, nullable=False, server_default="1"),
sa.Column("isbn", sa.Text, unique=True),
sa.CheckConstraint("year > 0", name="books_year_check"),
sa.CheckConstraint("copies >= 0", name="books_copies_check"),
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_table("books")Хоёр CHECK нэртэй — Бүлэг 13-ын сүүлийн хичээлийн сургамж: дүрэм зөрчигдөхөд алдааны мессеж бидний өгсөн нэрээр хэлнэ.
Migration 3: холбогч хүснэгт ба зээлүүд
powershell
alembic revision -m "create book_authors and loans"python
def upgrade() -> None:
"""Upgrade schema."""
op.create_table(
"book_authors",
sa.Column("book_id", sa.Integer, sa.ForeignKey("books.id", ondelete="CASCADE"), nullable=False),
sa.Column("author_id", sa.Integer, sa.ForeignKey("authors.id", ondelete="RESTRICT"), nullable=False),
sa.PrimaryKeyConstraint("book_id", "author_id"),
)
op.create_table(
"loans",
sa.Column("id", sa.Integer, sa.Identity(always=True), primary_key=True),
sa.Column("book_id", sa.Integer, sa.ForeignKey("books.id", ondelete="RESTRICT"), nullable=False),
sa.Column("member_id", sa.Integer, sa.ForeignKey("members.id", ondelete="RESTRICT"), nullable=False),
sa.Column("loaned_on", sa.Date, nullable=False, server_default=sa.text("CURRENT_DATE")),
sa.Column("due_on", sa.Date, nullable=False),
sa.Column("returned_on", sa.Date),
sa.CheckConstraint("due_on >= loaned_on", name="loans_due_check"),
sa.CheckConstraint(
"returned_on IS NULL OR returned_on >= loaned_on", name="loans_return_check"
),
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_table("loans")
op.drop_table("book_authors")Энэ migration Бүлэг 5-ын бүх гурван хичээлийг агуулна. sa.ForeignKey("books.id", ondelete="CASCADE") — FOREIGN KEY ... ON DELETE CASCADE: ном устгагдвал түүний зохиогчийн холбоосууд хамт явна. Зохиогч талд RESTRICT: номтой зохиогчийг устгаж болохгүй. sa.PrimaryKeyConstraint("book_id", "author_id") — олон-олон харилцааны хичээлийн нийлмэл PRIMARY KEY. Зээлийн FOREIGN KEY-үүд RESTRICT — Бүлэг 5-ын ON DELETE хичээлийн шийдвэр: зээлийн түүхтэй ном эсвэл гишүүнийг устгахгүй, оронд нь is_active-ээр идэвхгүй болгоно. downgrade() эсрэг дарааллаар: эхлээд заалт хийдэг loans ба book_authors, Migration 1 ба 2 эцэг эхчүүдийг өөрсдийн downgrade-д устгана.
Ажиллуулахаас өмнө Бүлэг 13-ын дадлаар SQL-ийг харъя:
powershell
alembic upgrade head --sqlГаралт таны library_pg.sql-тэй маш төстэй CREATE TABLE-үүдийг, тус бүрийн ард alembic_version-ийн INSERT эсвэл UPDATE-ийг харуулна. Уншаад тохирч байвал:
powershell
alembic upgrade headINFO [alembic.runtime.migration] Running upgrade -> 1a2b3c4d5e6f, create members and authors
INFO [alembic.runtime.migration] Running upgrade 1a2b3c4d5e6f -> 7f8e9d0c1b2a, create books
INFO [alembic.runtime.migration] Running upgrade 7f8e9d0c1b2a -> 3c4d5e6f7a8b, create book_authors and loansГурван migration дараалан. (Таны дугаарууд өөр байх.) Одоо мэргэжлийн нэг шалгалт: бүх migration буцаагдах эсэх. Хоосон өгөгдлийн сан дээр энэ шалгалт аюулгүй — алдах өгөгдөл байхгүй:
powershell
alembic downgrade base
alembic upgrade headbase гэдэг нь "гинжний эхлэл — бүх migration-ий өмнөх байдал." Эхний тушаал гурван downgrade-ийг эсрэг дарааллаар ажиллуулж хүснэгтүүдийг устгана, хоёр дахь нь дахин бүтээнэ. Хоёулаа алдаагүй дуусвал downgrade функцууд бүгд зөв гэдгийг баталлаа — жишээлбэл Migration 3-ын downgrade loans-ийг устгахаа мартсан бол Migration 2-ын drop_table("books") FOREIGN KEY-ээс болж бүтэлгүйтэх байсан. Үүнийг өгөгдөл орохоос өмнө, одоо олох нь хамгийн хямд.
psql-ээр бүтцийг харъя:
powershell
psql -U postgres -d library_final -c "\dt" List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------
public | alembic_version | table | postgres
public | authors | table | postgres
public | book_authors | table | postgres
public | books | table | postgres
public | loans | table | postgres
public | members | table | postgres
(6 rows)Таван хүснэгт, мөн Alembic-ийн хувилбарын хүснэгт. Commit хийх цаг:
powershell
git add .
git commit -m "Library schema as three migrations"Өгөгдлийг migration-д биш, тусдаа скриптэд бичнэ. Энэ ялгаа чухал. Migration бол бүтэц: бүх орчинд — таны компьютер, багийн гишүүдийн компьютер, жинхэнэ server — яг ижил ажиллах ёстой. Туршилтын өгөгдөл бол зөвхөн хөгжүүлэлтийн орчинд хэрэгтэй тавилга: жинхэнэ server дээр "Гишүүн 1"-ээс "Гишүүн 2000" хүртэл хуурамч хүмүүс бий болох ёсгүй. (Бүлэг 13-ын сүүлийн хичээлийн data migration бол өөр зүйл — тэр бүх орчны жинхэнэ өгөгдлийг бүтцийн өөрчлөлтөд нийцүүлдэг.)
capstone хавтсанд seed.sql (VS Code, UTF-8):
sql
BEGIN;
INSERT INTO members (name, email, city, joined_on)
SELECT 'Гишүүн ' || n,
'member' || n || '@example.mn',
(ARRAY['Улаанбаатар', 'Дархан', 'Эрдэнэт', 'Ховд', 'Чойбалсан'])[1 + n % 5],
DATE '2024-01-01' + n % 365
FROM generate_series(1, 2000) AS n;
INSERT INTO authors (name)
SELECT 'Зохиогч ' || n
FROM generate_series(1, 300) AS n;
INSERT INTO books (title, year, genre, copies, isbn)
SELECT 'Ном ' || n,
1950 + n % 75,
(ARRAY['Програмчлал', 'Түүх', 'Уран зохиол', 'Шинжлэх ухаан', 'Хүүхдийн'])[1 + n % 5],
2 + n % 5,
'978-99978-' || lpad(n::text, 4, '0')
FROM generate_series(1, 500) AS n;
INSERT INTO book_authors (book_id, author_id)
SELECT n, 1 + n % 300 FROM generate_series(1, 500) AS n
UNION ALL
SELECT n, 1 + (n * 7 + 1) % 300 FROM generate_series(1, 500) AS n WHERE n % 4 = 0;
INSERT INTO loans (book_id, member_id, loaned_on, due_on, returned_on)
SELECT 1 + (n * 101) % 500,
1 + (n * 37) % 2000,
DATE '2025-01-01' + n % 650,
DATE '2025-01-01' + n % 650 + 14,
CASE
WHEN DATE '2025-01-01' + n % 650 >= DATE '2026-10-01' AND n % 4 = 0 THEN NULL
ELSE LEAST(DATE '2025-01-01' + n % 650 + n % 20, DATE '2026-10-19')
END
FROM generate_series(1, 30000) AS n;
COMMIT;Энэ скриптэд хоёр шинэ хэрэгсэл, нэг танил загвар бий. Танил нь Бүлэг 14-ийн N+1 хичээлийн generate_series ба % тараах томъёо. Шинэ хэрэгслүүд: (ARRAY[...])[1 + n % 5] — PostgreSQL-ийн массив: таван хотын жагсаалтаас 1 + n % 5 дугаартайг сонго (PostgreSQL-ийн массив 1-ээс эхэлж тоологддог, тиймээс 1 +). lpad(n::text, 4, '0') — тоог текст болгоод зүүн талаас нь тэгээр дөрвөн оронтой болгох: 7 → ‘0007’. ::text бол параметргүй газар тул асуудалгүй (Бүлэг 14-ийн сүүлийн хичээлийн урхи зөвхөн параметрт хамаатай).
Скриптийг уншъя. Гишүүд: “1-ээс 2000 хүртэлх тоо бүрт нэр, давтагдашгүй и-мэйл, таван хотоос нэг, 2024 оны аль нэг өдөр элссэн гишүүн нэм.” Номнууд: 500 ном, таван төрөлд тархсан, 2-оос 6 хувьтай, давтагдашгүй ISBN-тэй. Зохиогчийн холбоос: ном бүр нэг зохиогчтой, мөн дөрөв дэх ном бүр хоёр дахь зохиогчтой — UNION ALL хоёр SELECT-ийн мөрүүдийг нэгтгэдэг. Хоёр дахь томъёо эхнийхтэй хэзээ ч давхцахгүй тул нийлмэл PRIMARY KEY зөрчигдөхгүй. Зээлүүд: 30 000 зээл 2025 оны 1-р сарын 1-ээс 2026 оны 10-р сарын 12 хүртэл тархсан, хугацаа нь 14 хоног. CASE: 2026 оны 10-р сараас хойш авсан зээлийн дөрөв дэх нь бүр буцаагдаагүй (NULL); бусад нь 0-19 хоногийн дараа буцаагдсан — 14-өөс хойш буцаасан нь хоцорсон буцаалт. LEAST — хоёр утгын багыг сонгодог функц: буцаасан огноо 2026-10-19-өөс хэтрэхгүй, ирээдүйд буцаагдсан зээл гарахгүй.
Бүх скрипт BEGIN ... COMMIT-д — Бүлэг 12: аль нэг INSERT бүтэлгүйтвэл юу ч орохгүй, хагас дүүрсэн өгөгдлийн сан үлдэхгүй. Ажиллуулна:
powershell
psql -U postgres -d library_final -v ON_ERROR_STOP=1 -f seed.sql-v ON_ERROR_STOP=1 нь psql-д "алдаа гарвал тэр даруй зогс" гэж хэлдэг. Үүнгүйгээр psql алдааны дараа ч дараагийн мөрүүдийг үргэлжлүүлэн ажиллуулж, Бүлэг 12-ын "аборт болсон transaction" байдалд мэдэгдэл хэвлэсээр байх байсан. Амжилттай бол:
BEGIN
INSERT 0 2000
INSERT 0 300
INSERT 0 500
INSERT 0 625
INSERT 0 30000
COMMITINSERT 0 2000 юу гэж хэлж байна вэ гэвэл: “2000 мөр нэмэгдлээ” (эхний 0 нь хуучин PostgreSQL-ийн үлдэц, тоохгүй байж болно). Зохиогчийн холбоос 625 = 500 + 125.
Тоог итгэхээс өмнө шалгая. psql-ээр:
sql
SELECT 'members' AS tbl, COUNT(*) FROM members
UNION ALL SELECT 'authors', COUNT(*) FROM authors
UNION ALL SELECT 'books', COUNT(*) FROM books
UNION ALL SELECT 'book_authors', COUNT(*) FROM book_authors
UNION ALL SELECT 'loans', COUNT(*) FROM loans; tbl | count
--------------+-------
members | 2000
authors | 300
books | 500
book_authors | 625
loans | 30000
(5 rows)Энэ query юу гэж хэлж байна вэ гэвэл: "хүснэгт бүрийн мөрийн тоог нэрийнх нь хамт нэг хүснэгтэд ав." Буцаагдаагүй зээлүүд:
sql
SELECT COUNT(*) FROM loans WHERE returned_on IS NULL; count
-------
138
(1 row)Энэ тоо санамсаргүй биш — seed.sql-ийн томъёоноос тодорхойлогддог, тиймээс таных яг 138 байх ёстой. Хэрэв өөр бол скрипт хуулахдаа өөрчлөгдсөн байна. Сүүлд нь өгөгдлийн хэлбэрийг Бүлэг 8-ын GROUP BY-гаар харъя:
sql
SELECT genre, COUNT(*) AS books, SUM(copies) AS copies
FROM books
GROUP BY genre
ORDER BY genre; genre | books | copies
---------------+-------+--------
Програмчлал | 100 | 400
Түүх | 100 | 400
Уран зохиол | 100 | 400
Хүүхдийн | 100 | 400
Шинжлэх ухаан | 100 | 400
(5 rows)Төрөл бүрт 100 ном, нийт 400 хувь. Эрэмбэ Бүлэг 2-ын кирилл эрэмбийн анхааруулгатай нийцэж байгаа эсэхийг өөрийн нүдээр хараарай — таны PostgreSQL-ийн collation тохиргооноос хамааран дараалал бага зэрэг өөр байж болно.
Даатгалын цаг. PostgreSQL-ийн pg_dump хэрэгсэл өгөгдлийн санг бүхэлд нь — бүтэц, өгөгдөл, alembic_version хүртэл — нэг файлд бичдэг. Бүлэг 10-т PATH тохируулсан тул psql-ийн хажууд шууд ажиллана:
powershell
pg_dump -U postgres -d library_final -F c -f library_final_2026-10-10.dumpЭнэ тушаал юу гэж хэлж байна вэ гэвэл: “library_final санг custom хэлбэрээр (-F c) энэ файлд хадгал.” Custom хэлбэр шахагдсан, хоёртын файл бөгөөд зөвхөн pg_restore-оор сэргээгддэг; түүний давуу тал нь хүснэгт бүрийг тусад нь сэргээх зэрэг уян хатан боломж. Файлын нэрэнд огноо — backup-ууд хуримтлагдахад аль нь хэзээх болохыг нэрнээс нь мэднэ.
Backup-ыг хийсэн нь сэргээж чадна гэсэн үг биш. Шалгая — шинэ хоосон санд сэргээж:
powershell
psql -U postgres -c "CREATE DATABASE library_restore"
pg_restore -U postgres -d library_restore library_final_2026-10-10.dump
psql -U postgres -d library_restore -c "SELECT COUNT(*) FROM loans"
psql -U postgres -d library_restore -c "SELECT version_num FROM alembic_version"Эхний query 30000, хоёр дахь нь таны сүүлийн migration-ий дугаар (3c4d5e6f7a8b гэх мэт) буцаавал backup бүрэн: өгөгдөл ба migration-ий байдал хоёулаа. Энэ нь сэргээсэн санд alembic upgrade head хийхэд Alembic аль migration хүртэл хэрэгжсэнийг зөв мэднэ гэсэн үг. Туршилтын санг устгая:
powershell
psql -U postgres -c "DROP DATABASE library_restore"Одоо .gitignore-ийн *.dump мөрийн учир. Backup файл бол өгөгдөл — бодит төсөлд гишүүдийн нэр, и-мэйл. Git бол кодын түүх бөгөөд олон хүнд, олон газарт хуулагддаг. Өгөгдлийг тэнд хийх нь Бүлэг 11-ийн нууц үгийг кодонд бичихтэй адил алдаа. Мөн том хоёртын файл Git-ийн түүхийг үүрд хүндрүүлдэг. Backup өөрийн газарт — тусдаа диск, үүлэн хадгалалт — хадгалагдана.
Харин бүтцийг хүний уншихуйц хэлбэрээр харах тустай:
powershell
pg_dump -U postgres -d library_final --schema-only -f schema_snapshot.sql--schema-only нь "өгөгдөлгүй, зөвхөн бүтэц." VS Code-оор schema_snapshot.sql-ийг нээвэл гурван migration-ий үр дүнг PostgreSQL-ийн өөрийн хэлээр — CREATE TABLE, бүх нэртэй CONSTRAINT, FOREIGN KEY ... ON DELETE — харна. Бүлэг 10-ын library_pg.sql-тэй хажуу хажууд нь тавьж харьцуулаарай: ижил schema, өөр замаар бүтээгдсэн. Энэ файлыг Git-д хийж болно — өгөгдөл агуулаагүй.
powershell
git add .
git commit -m "Seed script and schema snapshot"Хэрэв сонирхож байвал seed.sql-д буцаагдаагүй зээлийн нөхцөлийг өөрчилж (жишээлбэл n % 4-ийг n % 3 болгож) хэдэн зээл буцаагдаагүй болохыг ажиллуулахаасаа өмнө тооцоолж үзээрэй — 138 хэрхэн гарсныг томъёоноос гаргах нь сайхан бодлого. Дараа нь alembic downgrade base, alembic upgrade head, seed-ийг дахин ажиллуулж таамаглалаа шалгаарай. Эсвэл pg_restore-ийн --table=loans сонголтоор зөвхөн нэг хүснэгтийг сэргээж үзээрэй. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Seed-д id-г гараар бичих. INSERT INTO members (id, name) VALUES (1, 'Бат') гэвэл:
ERROR: cannot insert a non-DEFAULT value into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.Энэ мессеж юу гэж хэлж байна вэ гэвэл: “id баганад DEFAULT биш утга оруулах боломжгүй; энэ багана GENERATED ALWAYS identity.” Бүлэг 4-ийн PRIMARY KEY хичээлд энэ хамгаалалтыг танилцуулсан. Seed-д id-г орхи — бидний скрипт 1 + n % 300 гэх мэтээр заалт хийхдээ id 1-ээс дараалан үүснэ гэдэгт тулгуурласан, энэ нь шинэ санд үнэн.
Seed-ийг хоёр дахь удаа ажиллуулах. Тэр үед id 2001-ээс эхэлж, ERROR: duplicate key value violates unique constraint "members_email_key" гарна — и-мэйл давхцсан. BEGIN-ийн ачаар юу ч орохгүй. Seed-ийг дахин хийх бол цэвэр эхлэл: alembic downgrade base, alembic upgrade head, тэгээд seed.
Custom backup-ыг psql-ээр сэргээх гэж оролдох. psql -f library_final_2026-10-10.dump гэвэл: The input is a PostgreSQL custom-format dump. Use the pg_restore command-line client to restore this dump to a database. — "оролт бол PostgreSQL-ийн custom хэлбэрийн dump; сэргээхэд pg_restore ашигла." psql зөвхөн текстэн SQL-ийг ажиллуулдаг.
Байхгүй сан руу сэргээх. pg_restore -d library_restore ... гэхэд database "library_restore" does not exist гарвал CREATE DATABASE-ийг эхэлж хий. pg_restore анхдагчаар санг үүсгэдэггүй.
Backup-ыг хэзээ ч сэргээж туршаагүй байх. Алдааны мессеж гарахгүй, хамгийн аюултай алдаа. Сэргээгдэхгүй backup-ыг хэрэгтэй болсон өдөр л мэддэг — тэр өдөр хэтэрхий оройтсон. Алхам 6-ийн туршилтыг backup хийх журам бүрийн нэг хэсэг гэж үз.
Энэ хичээлд та Номын сангийн системийг хоосон сангаас мэргэжлийн аргаар бүтээлээ. Бүтэц гурван migration-д — гишүүд ба зохиогчид, номнууд, холбогч хүснэгт ба зээлүүд — FOREIGN KEY-ийн дарааллаар хуваагдсан; Identity, server талын DEFAULT, нэртэй CHECK, ON DELETE CASCADE/RESTRICT, нийлмэл PRIMARY KEY бүгд Python-оор илэрхийлэгдсэн. --sql урьдчилан харах, downgrade base ба upgrade head-ийн бүтэн мөчлөг өгөгдөл орохоос өмнө бүх downgrade зөв гэдгийг баталсан. Туршилтын өгөгдөл migration-д биш, transaction-д ороосон тусдаа seed.sql-д — generate_series, массив, lpad, UNION ALL, LEAST-ээр 2000 гишүүн, 500 ном, 30 000 зээл, тодорхойлогдсон 138 буцаагдаагүй зээл — ON_ERROR_STOP-той ажиллаж, тоонууд шалгагдсан. pg_dump -F c backup хийж, шинэ санд pg_restore-оор сэргээж, өгөгдөл ба alembic_version хоёулаа бүрэн болохыг баталсан; backup Git-ээс гадна, бүтцийн зураг Git-д.
Дараагийн хичээлд энэ сан дээр ажил эхэлнэ: тайлангуудыг 30 000 зээл дээр ажиллуулж, EXPLAIN ANALYZE-ээр хэмжиж, хэрэгтэй index-үүдийг шинэ migration-оор нэмж ялгааг хэмжинэ, тэгээд ном олгох үйлдлийг — хувь хүрэлцэх эсэхийг шалгаж, зээл бичиж — транзакцтай, түгжээтэй Python функц болгон бичнэ.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.