17. SQLite va ma’lumotlar bazasi¶
Dasturlashda ma’lumotlarni fayllarda saqlash har doim ham yetarli emas.
Masalan, Softromeda uchun quyidagi ma’lumotlarni saqlash kerak bo‘lishi mumkin:
foydalanuvchilar
mahsulotlar
buyurtmalar
to‘lovlar
xabarlar
loyihalar
Ma’lumotlar soni ko‘payganda oddiy JSON yoki CSV fayllari bilan ishlash qiyinlashadi.
Bunday vaziyatlarda ma’lumotlar bazasi ishlatiladi.
Python'da kichik va o‘rta loyihalar uchun juda qulay ma’lumotlar bazalaridan biri — SQLite.
Bu bobda:
- ma’lumotlar bazasi nima?
- SQLite
- ma’lumotlar bazasiga ulanish
- jadval yaratish
INSERTSELECTUPDATEDELETE- tranzaksiyalar
mavzularini o‘rganamiz.
Ma’lumotlar bazasi nima?¶
Ma’lumotlar bazasi — ma’lumotlarni tartibli ravishda saqlash, izlash, o‘zgartirish va o‘chirish uchun ishlatiladigan tizim.
Masalan, foydalanuvchilar jadvali:
id ism yosh shahar
1 Ali 25 Toshkent
2 Vali 30 Samarqand
3 Sami 22 Buxoro
Bu yerda:
id
ism
yosh
shahar
ustunlar hisoblanadi.
Har bir foydalanuvchi esa alohida qator.
Ma’lumotlar bazasi bilan ishlash¶
Ma’lumotlar bazasida odatda quyidagi amallar bajariladi:
CREATE
INSERT
SELECT
UPDATE
DELETE
Ularning ma’nosi:
CREATE → yaratish
INSERT → qo‘shish
SELECT → o‘qish
UPDATE → o‘zgartirish
DELETE → o‘chirish
Bu amallar ko‘pincha SQL tili orqali bajariladi.
SQLite¶
SQLite — alohida server talab qilmaydigan ma’lumotlar bazasi.
Python'da SQLite bilan ishlash uchun alohida kutubxona o‘rnatish shart emas.
Python standart kutubxonasida:
sqlite3
moduli mavjud.
Uni:
import sqlite3
orqali ishlatamiz.
SQLite fayli¶
SQLite ma’lumotlar bazasini bitta faylda saqlashi mumkin.
Masalan:
softromeda.db
Bu fayl ichida jadvallar va ularning ma’lumotlari saqlanadi.
Ma’lumotlar bazasiga ulanish¶
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
print(
"Ma'lumotlar bazasiga ulanish muvaffaqiyatli."
)
ulanish.close()
connect()¶
Quyidagi kod:
sqlite3.connect(
"softromeda.db"
)
agar fayl mavjud bo‘lmasa, uni yaratadi.
Agar mavjud bo‘lsa, shu ma’lumotlar bazasiga ulanadi.
Ulanishni yopish¶
Ish tugagach ulanishni yopish kerak:
ulanish.close()
To‘liq ko‘rinish:
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
print(
"Ulanish amalga oshirildi."
)
ulanish.close()
print(
"Ulanish yopildi."
)
Kursor¶
SQL buyruqlarini bajarish uchun cursor kerak.
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
print(
"Kursor yaratildi."
)
ulanish.close()
Kursor SQL buyruqlarini bajarish va natijalarni olish uchun ishlatiladi.
Jadval yaratish¶
Foydalanuvchilar jadvalini yaratamiz.
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
kursor.execute(
"""
CREATE TABLE IF NOT EXISTS foydalanuvchilar (
id INTEGER PRIMARY KEY,
ism TEXT NOT NULL,
yosh INTEGER,
shahar TEXT
)
"""
)
ulanish.commit()
ulanish.close()
Jadval ustunlari¶
Yuqoridagi jadval:
id
ism
yosh
shahar
ustunlaridan tashkil topgan.
id:
INTEGER PRIMARY KEY
sifatida belgilangan.
Bu foydalanuvchini yagona identifikatsiya qilishga yordam beradi.
TEXT¶
Matn saqlash uchun:
TEXT
ishlatiladi.
Masalan:
ism TEXT
INTEGER¶
Butun sonlar uchun:
INTEGER
ishlatiladi.
Masalan:
yosh INTEGER
NOT NULL¶
Agar qiymat majburiy bo‘lishi kerak bo‘lsa:
NOT NULL
ishlatiladi.
Masalan:
ism TEXT NOT NULL
Bu foydalanuvchining ismi bo‘sh bo‘lishiga yo‘l qo‘ymaydi.
INSERT¶
Jadvalga ma’lumot qo‘shish uchun INSERT ishlatiladi.
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
kursor.execute(
"""
INSERT INTO foydalanuvchilar
(ism, yosh, shahar)
VALUES (?, ?, ?)
""",
(
"Ali",
25,
"Toshkent"
)
)
ulanish.commit()
ulanish.close()
Nima uchun ? ishlatiladi?¶
SQL so‘roviga qiymatlarni to‘g‘ridan-to‘g‘ri qo‘shish tavsiya etilmaydi.
Masalan, bunday yozish xavfli:
ism = "Ali"
kursor.execute(
f"""
INSERT INTO foydalanuvchilar
(ism)
VALUES ('{ism}')
"""
)
Buning o‘rniga parametrli so‘rov ishlatiladi:
kursor.execute(
"""
INSERT INTO foydalanuvchilar
(ism)
VALUES (?)
""",
(ism,)
)
Bu SQL injection kabi muammolardan himoyalanishga yordam beradi.
Bir nechta ma’lumot qo‘shish¶
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
foydalanuvchilar = [
("Ali", 25, "Toshkent"),
("Vali", 30, "Samarqand"),
("Sami", 22, "Buxoro")
]
kursor.executemany(
"""
INSERT INTO foydalanuvchilar
(ism, yosh, shahar)
VALUES (?, ?, ?)
""",
foydalanuvchilar
)
ulanish.commit()
ulanish.close()
executemany()¶
executemany() bir xil SQL buyruğini bir nechta ma’lumot bilan bajarishga yordam beradi.
Masalan:
kursor.executemany(
"""
INSERT INTO foydalanuvchilar
(ism, yosh, shahar)
VALUES (?, ?, ?)
""",
foydalanuvchilar
)
SELECT¶
Ma’lumotlarni olish uchun:
SELECT
ishlatiladi.
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
kursor.execute(
"""
SELECT * FROM foydalanuvchilar
"""
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
ulanish.close()
fetchall()¶
fetchall() barcha natijalarni qaytaradi.
Masalan:
foydalanuvchilar = kursor.fetchall()
Natija:
[
(1, 'Ali', 25, 'Toshkent'),
(2, 'Vali', 30, 'Samarqand'),
(3, 'Sami', 22, 'Buxoro')
]
fetchone()¶
Faqat bitta natijani olish:
kursor.execute(
"""
SELECT * FROM foydalanuvchilar
"""
)
foydalanuvchi = kursor.fetchone()
print(
foydalanuvchi
)
fetchmany()¶
Bir nechta natijani olish:
kursor.execute(
"""
SELECT * FROM foydalanuvchilar
"""
)
foydalanuvchilar = kursor.fetchmany(
2
)
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
Faqat kerakli ustunlarni olish¶
Barcha ustunlarni:
SELECT *
orqali olish mumkin.
Lekin faqat kerakli ustunlarni olish yaxshiroq:
kursor.execute(
"""
SELECT ism, shahar
FROM foydalanuvchilar
"""
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
f"Ism: {foydalanuvchi[0]}, "
f"Shahar: {foydalanuvchi[1]}"
)
WHERE¶
Muayyan shartga mos ma’lumotlarni olish uchun WHERE ishlatiladi.
Masalan, 25 yoshdan katta foydalanuvchilar:
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
WHERE yosh > ?
""",
(25,)
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
Ism bo‘yicha qidirish¶
ism = "Ali"
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
WHERE ism = ?
""",
(ism,)
)
foydalanuvchi = kursor.fetchone()
print(
foydalanuvchi
)
ORDER BY¶
Ma’lumotlarni tartiblash uchun ORDER BY ishlatiladi.
Yosh bo‘yicha o‘sish tartibida:
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
ORDER BY yosh ASC
"""
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
Kamayish tartibi¶
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
ORDER BY yosh DESC
"""
)
LIMIT¶
Natijalar sonini cheklash mumkin.
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
LIMIT 2
"""
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
UPDATE¶
Mavjud ma’lumotni o‘zgartirish uchun:
UPDATE
ishlatiladi.
Masalan, Ali yoshini o‘zgartirish:
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
kursor.execute(
"""
UPDATE foydalanuvchilar
SET yosh = ?
WHERE ism = ?
""",
(
26,
"Ali"
)
)
ulanish.commit()
ulanish.close()
Bir nechta ustunni o‘zgartirish¶
kursor.execute(
"""
UPDATE foydalanuvchilar
SET yosh = ?, shahar = ?
WHERE ism = ?
""",
(
26,
"Toshkent",
"Ali"
)
)
DELETE¶
Ma’lumotni o‘chirish uchun:
DELETE
ishlatiladi.
kursor.execute(
"""
DELETE FROM foydalanuvchilar
WHERE ism = ?
""",
("Ali",)
)
ulanish.commit()
DELETE bilan ehtiyot bo‘lish¶
Quyidagi so‘rov:
DELETE FROM foydalanuvchilar
jadvaldagi barcha ma’lumotlarni o‘chiradi.
Shuning uchun odatda WHERE shartidan foydalanish kerak:
DELETE FROM foydalanuvchilar
WHERE id = ?
commit()¶
Ma’lumotlarni o‘zgartiradigan SQL amallaridan keyin:
ulanish.commit()
ishlatiladi.
Masalan:
kursor.execute(
"""
INSERT INTO foydalanuvchilar
(ism, yosh)
VALUES (?, ?)
""",
(
"Sami",
22
)
)
ulanish.commit()
commit() bajarilmasa, o‘zgarishlar doimiy saqlanmasligi mumkin.
rollback()¶
Agar xatolik yuz bersa, o‘zgarishlarni bekor qilish mumkin.
ulanish.rollback()
Masalan:
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
try:
kursor.execute(
"""
INSERT INTO foydalanuvchilar
(ism, yosh)
VALUES (?, ?)
""",
(
"Ali",
25
)
)
ulanish.commit()
except sqlite3.Error:
ulanish.rollback()
print(
"Xatolik yuz berdi. "
"O‘zgarishlar bekor qilindi."
)
finally:
ulanish.close()
Tranzaksiya¶
Tranzaksiya — bir nechta ma’lumotlar bazasi amalini bitta mantiqiy operatsiya sifatida bajarish.
Masalan, bank tizimida:
bir hisobdan pul ayirish
boshqa hisobga pul qo‘shish
ikkalasi ham muvaffaqiyatli bajarilishi kerak.
Agar birinchi amal bajarilib, ikkinchisi xato bersa, tizim noto‘g‘ri holatga kelishi mumkin.
Tranzaksiya bunday vaziyatlarda juda muhim.
Tranzaksiya misoli¶
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
try:
kursor.execute(
"""
UPDATE hisoblar
SET balans = balans - ?
WHERE id = ?
""",
(
100,
1
)
)
kursor.execute(
"""
UPDATE hisoblar
SET balans = balans + ?
WHERE id = ?
""",
(
100,
2
)
)
ulanish.commit()
print(
"Tranzaksiya muvaffaqiyatli bajarildi."
)
except sqlite3.Error:
ulanish.rollback()
print(
"Tranzaksiya bekor qilindi."
)
finally:
ulanish.close()
with yordamida ulanish¶
SQLite ulanishini with orqali boshqarish ham mumkin.
import sqlite3
with sqlite3.connect(
"softromeda.db"
) as ulanish:
kursor = ulanish.cursor()
kursor.execute(
"""
INSERT INTO foydalanuvchilar
(ism, yosh)
VALUES (?, ?)
""",
(
"Sami",
22
)
)
Bu usul resurslarni boshqarishni osonlashtiradi.
row_factory¶
Oddiy fetchall() natijani tuple ko‘rinishida qaytaradi:
(1, 'Ali', 25, 'Toshkent')
Lekin ustun nomlari bilan ishlash qulayroq bo‘lishi mumkin.
Buning uchun:
sqlite3.Row
ishlatish mumkin.
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
ulanish.row_factory = sqlite3.Row
kursor = ulanish.cursor()
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
"""
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
f"Ism: {foydalanuvchi['ism']}"
)
print(
f"Yosh: {foydalanuvchi['yosh']}"
)
ulanish.close()
Bu usul katta dasturlarda kodni ancha tushunarli qiladi.
COUNT¶
Jadvaldagi yozuvlar sonini hisoblash:
kursor.execute(
"""
SELECT COUNT(*)
FROM foydalanuvchilar
"""
)
natija = kursor.fetchone()
print(
f"Foydalanuvchilar soni: {natija[0]}"
)
AVG¶
O‘rtacha yoshni hisoblash:
kursor.execute(
"""
SELECT AVG(yosh)
FROM foydalanuvchilar
"""
)
natija = kursor.fetchone()
print(
f"O‘rtacha yosh: {natija[0]}"
)
MAX va MIN¶
Eng katta yosh:
kursor.execute(
"""
SELECT MAX(yosh)
FROM foydalanuvchilar
"""
)
eng_katta_yosh = kursor.fetchone()[0]
print(
f"Eng katta yosh: {eng_katta_yosh}"
)
Eng kichik yosh:
kursor.execute(
"""
SELECT MIN(yosh)
FROM foydalanuvchilar
"""
)
eng_kichik_yosh = kursor.fetchone()[0]
print(
f"Eng kichik yosh: {eng_kichik_yosh}"
)
LIKE¶
Matn bo‘yicha qisman qidirish uchun LIKE ishlatiladi.
Masalan, ism A harfi bilan boshlansa:
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
WHERE ism LIKE ?
""",
(
"A%",
)
)
foydalanuvchilar = kursor.fetchall()
for foydalanuvchi in foydalanuvchilar:
print(
foydalanuvchi
)
Bu yerda:
% → istalgan miqdordagi belgilar
ni bildiradi.
Jadval mavjudligini tekshirish¶
SQLite'da jadvallar haqida ma’lumot olish mumkin:
kursor.execute(
"""
SELECT name
FROM sqlite_master
WHERE type = 'table'
"""
)
jadvallar = kursor.fetchall()
for jadval in jadvallar:
print(
f"Jadval: {jadval[0]}"
)
Amaliy loyiha — Softromeda foydalanuvchilar bazasi¶
Endi kichik foydalanuvchilar boshqaruv tizimini yaratamiz.
Dastur:
ma’lumotlar bazasini yaratadi
foydalanuvchilar jadvalini yaratadi
foydalanuvchilar qo‘shadi
foydalanuvchilarni ko‘rsatadi
foydalanuvchini qidiradi
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
ulanish.row_factory = sqlite3.Row
kursor = ulanish.cursor()
kursor.execute(
"""
CREATE TABLE IF NOT EXISTS foydalanuvchilar (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ism TEXT NOT NULL,
yosh INTEGER NOT NULL,
shahar TEXT NOT NULL
)
"""
)
foydalanuvchilar = [
(
"Ali",
25,
"Toshkent"
),
(
"Vali",
30,
"Samarqand"
),
(
"Sami",
22,
"Buxoro"
)
]
kursor.executemany(
"""
INSERT INTO foydalanuvchilar
(ism, yosh, shahar)
VALUES (?, ?, ?)
""",
foydalanuvchilar
)
ulanish.commit()
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
ORDER BY id
"""
)
barcha_foydalanuvchilar = (
kursor.fetchall()
)
print(
"=== Softromeda foydalanuvchilari ==="
)
for foydalanuvchi in barcha_foydalanuvchilar:
print(
f"ID: {foydalanuvchi['id']}"
)
print(
f"Ism: {foydalanuvchi['ism']}"
)
print(
f"Yosh: {foydalanuvchi['yosh']}"
)
print(
f"Shahar: {foydalanuvchi['shahar']}"
)
print(
"--------------------"
)
qidirilayotgan_ism = "Ali"
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
WHERE ism = ?
""",
(
qidirilayotgan_ism,
)
)
foydalanuvchi = kursor.fetchone()
if foydalanuvchi:
print(
f"Topildi: "
f"{foydalanuvchi['ism']}"
)
else:
print(
"Foydalanuvchi topilmadi."
)
ulanish.close()
Ma’lumotlar bazasi bilan ishlashning umumiy sxemasi¶
Python'da SQLite bilan ishlashda ko‘pincha quyidagi tartibdan foydalanamiz:
1. sqlite3 import qilish
2. ma’lumotlar bazasiga ulanish
3. cursor yaratish
4. SQL buyruqlarini bajarish
5. natijani olish
6. commit qilish
7. ulanishni yopish
Masalan:
import sqlite3
ulanish = sqlite3.connect(
"softromeda.db"
)
kursor = ulanish.cursor()
kursor.execute(
"""
SELECT *
FROM foydalanuvchilar
"""
)
natijalar = kursor.fetchall()
for natija in natijalar:
print(
natija
)
ulanish.close()
SQL buyruqlarining asosiy guruhlari¶
Ma’lumotlar bazasida eng ko‘p uchraydigan buyruqlar:
CREATE
jadval yaratish
INSERT
ma’lumot qo‘shish
SELECT
ma’lumot olish
UPDATE
ma’lumot o‘zgartirish
DELETE
ma’lumot o‘chirish
Amaliy mashqlar¶
Mashq 1¶
softromeda.db ma’lumotlar bazasini yarating.
Mashq 2¶
mahsulotlar jadvalini yarating.
U quyidagi ustunlarga ega bo‘lsin:
id
nom
narx
miqdor
Mashq 3¶
Jadvalga 5 ta mahsulot qo‘shing.
Mashq 4¶
Barcha mahsulotlarni SELECT yordamida oling.
Mashq 5¶
Narxi 100 dan katta mahsulotlarni toping.
Mashq 6¶
Mahsulotlardan birining narxini UPDATE yordamida o‘zgartiring.
Mashq 7¶
Bir mahsulotni DELETE yordamida o‘chiring.
Mashq 8¶
Mahsulotlarning umumiy sonini COUNT() yordamida toping.
Mashq 9¶
Mahsulotlarning o‘rtacha narxini AVG() yordamida hisoblang.
Mashq 10¶
Softromeda uchun mahsulot boshqaruv tizimini yarating.
Dastur:
ma’lumotlar bazasini yaratsin
mahsulot qo‘shsin
mahsulotlarni ko‘rsatsin
mahsulot qidirsin
mahsulot narxini o‘zgartirsin
mahsulotni o‘chirsin
Bob xulosasi¶
Bu bobda SQLite bilan ishlashni o‘rgandik.
Asosiy modul:
import sqlite3
Asosiy amallar:
sqlite3.connect()
cursor()
execute()
executemany()
fetchone()
fetchmany()
fetchall()
commit()
rollback()
close()
Asosiy SQL buyruqlari:
CREATE
INSERT
SELECT
UPDATE
DELETE
Muhim tushunchalar:
ma’lumotlar bazasi
jadval
ustun
qator
primary key
SQL
kursor
tranzaksiya
commit
rollback
SQLite kichik va o‘rta Python loyihalari uchun juda qulay. U alohida server talab qilmaydi va butun ma’lumotlar bazasini bitta faylda saqlashi mumkin.
Keyingi bobda 18. API va HTTP bilan ishlash mavzusini o‘rganamiz.