🐍 آموزش جامع Python — پست ۱۹۱
جستوجوی چند مقدار با
در پست قبل با
حالا میخواهیم ببینیم چطور میتوانیم بررسی کنیم یک ستون، یکی از چند مقدار مشخص باشد.
برای این کار از:
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم میخواهیم دانشآموزانی را پیدا کنیم که نامشان
یعنی:
🔹 مقایسه با
بدون
اما
🔹 استفاده با چند مقدار
میتوانیم بیشتر از دو مقدار هم داشته باشیم:
در اینجا فقط رکوردهایی انتخاب میشوند که
🔹 استفاده با عدد
مثلاً میتوانیم چند
یعنی:
🔹 ساختن Placeholderها بهصورت پویا
گاهی تعداد مقادیر از قبل مشخص نیست.
مثلاً:
نمیتوانیم بهصورت ثابت بنویسیم:
اگر تعداد نامها تغییر کند.
میتوانیم Placeholderها را بسازیم:
در اینجا:
ساخته میشود.
⚠️ خود مقادیر همچنان با
🔹
اگر بخواهیم رکوردهایی را پیدا کنیم که مقدارشان در لیست موردنظر نباشد، از:
استفاده میکنیم.
مثلاً:
یعنی:
🔥 مثال کاربردی
فرض کنیم فقط میخواهیم دانشآموزان سه کلاس مشخص را بررسی کنیم:
این روش زمانی مفید است که تعداد مقادیر جستوجو متغیر باشد.
⚠️ نکته مهم
برای مقدارهای متغیر، از این روش استفاده نکن:
مقدارهای کاربر را مستقیماً داخل SQL قرار نده.
روش درست:
🧠 خلاصه
مثلاً:
یا:
و برای تعداد متغیر:
🎯 تمرین
کد زیر را کامل کن تا فقط دانشآموزانی که
کلمه مناسب را جایگزین کن:
پست ۱۹۱ از دوره جامع Python 🐍
جستوجوی چند مقدار با
IN در SQLiteدر پست قبل با
LIKE یاد گرفتیم چطور بخشی از یک متن را جستوجو کنیم.حالا میخواهیم ببینیم چطور میتوانیم بررسی کنیم یک ستون، یکی از چند مقدار مشخص باشد.
برای این کار از:
IN
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم میخواهیم دانشآموزانی را پیدا کنیم که نامشان
Ali یا Sara است:cursor.execute(
"SELECT * FROM students WHERE name IN (?, ?)",
("Ali", "Sara")
)
students = cursor.fetchall()
for student in students:
print(student)
یعنی:
name = "Ali"
یا
name = "Sara"
🔹 مقایسه با
ORبدون
IN میتوانستیم بنویسیم:cursor.execute(
"""
SELECT * FROM students
WHERE name = ? OR name = ?
""",
("Ali", "Sara")
)
اما
IN برای این نوع جستوجو خواناتر است:cursor.execute(
"SELECT * FROM students WHERE name IN (?, ?)",
("Ali", "Sara")
)
🔹 استفاده با چند مقدار
میتوانیم بیشتر از دو مقدار هم داشته باشیم:
cursor.execute(
"SELECT * FROM students WHERE name IN (?, ?, ?)",
("Ali", "Sara", "Reza")
)
در اینجا فقط رکوردهایی انتخاب میشوند که
name یکی از این سه مقدار باشد.🔹 استفاده با عدد
IN فقط برای رشتهها نیست.مثلاً میتوانیم چند
id مشخص را پیدا کنیم:cursor.execute(
"SELECT * FROM students WHERE id IN (?, ?, ?)",
(1, 3, 5)
)
یعنی:
id = 1
یا
id = 3
یا
id = 5
🔹 ساختن Placeholderها بهصورت پویا
گاهی تعداد مقادیر از قبل مشخص نیست.
مثلاً:
names = ["Ali", "Sara", "Reza"]
نمیتوانیم بهصورت ثابت بنویسیم:
IN (?, ?, ?)
اگر تعداد نامها تغییر کند.
میتوانیم Placeholderها را بسازیم:
names = ["Ali", "Sara", "Reza"]
placeholders = ",".join("?" for _ in names)
query = f"""
SELECT * FROM students
WHERE name IN ({placeholders})
"""
cursor.execute(query, names)
در اینجا:
names = 3 مقدار
↓
?, ?, ?
ساخته میشود.
⚠️ خود مقادیر همچنان با
? به Query داده میشوند.🔹
NOT INاگر بخواهیم رکوردهایی را پیدا کنیم که مقدارشان در لیست موردنظر نباشد، از:
NOT IN
استفاده میکنیم.
مثلاً:
cursor.execute(
"SELECT * FROM students WHERE name NOT IN (?, ?)",
("Ali", "Sara")
)
یعنی:
دانشآموزانی را پیدا کن که نامشان نه
Aliباشد و نه
Sara.
🔥 مثال کاربردی
فرض کنیم فقط میخواهیم دانشآموزان سه کلاس مشخص را بررسی کنیم:
class_names = ["Python", "Django", "Flask"]
placeholders = ",".join("?" for _ in class_names)
cursor.execute(
f"""
SELECT * FROM courses
WHERE name IN ({placeholders})
""",
class_names
)
courses = cursor.fetchall()
این روش زمانی مفید است که تعداد مقادیر جستوجو متغیر باشد.
⚠️ نکته مهم
برای مقدارهای متغیر، از این روش استفاده نکن:
query = f"""
SELECT * FROM students
WHERE name IN ({names})
"""
مقدارهای کاربر را مستقیماً داخل SQL قرار نده.
روش درست:
placeholders = ",".join("?" for _ in names)
cursor.execute(
f"SELECT * FROM students WHERE name IN ({placeholders})",
names
)🧠 خلاصه
IN → یکی از چند مقدار
NOT IN → هیچکدام از چند مقدار
مثلاً:
WHERE id IN (?, ?, ?)
یا:
WHERE name NOT IN (?, ?)
و برای تعداد متغیر:
placeholders = ",".join("?" for _ in values)🎯 تمرین
کد زیر را کامل کن تا فقط دانشآموزانی که
id آنها 1، 3 یا 5 است نمایش داده شوند:import sqlite3
connection = sqlite3.connect("school.db")
cursor = connection.cursor()
ids = [1, 3, 5]
placeholders = ",".join("?" for _ in ids)
cursor.execute(
f"""
SELECT * FROM students
WHERE id ______ ({placeholders})
""",
ids
)
students = cursor.fetchall()
for student in students:
print(student)
connection.close()
کلمه مناسب را جایگزین کن:
IN
پست ۱۹۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۲
محاسبه اطلاعات آماری با
تا اینجا بیشتر با دریافت و تغییر رکوردها کار کردیم.
اما در پروژههای واقعی گاهی لازم است بهجای نمایش تکتک رکوردها، روی دادهها محاسبه انجام دهیم.
SQLite چند تابع مهم برای این کار دارد:
در این پست با سه مورد اول آشنا میشویم.
🔹
مثلاً تعداد دانشآموزان:
اگر 10 دانشآموز داشته باشیم:
🔹 چرا
چون
به همین دلیل:
عدد
🔹 شمارش با شرط
میتوانیم فقط رکوردهایی را بشماریم که یک شرط مشخص دارند.
مثلاً تعداد دانشآموزانی که نمره حداقل
🔹
مثلاً مجموع نمرهها:
اگر نمرهها:
باشند:
🔹
برای نمرههای:
نتیجه:
🔥 ترکیب چند تابع
میتوانیم چند تابع آماری را در یک Query استفاده کنیم:
مثلاً:
🔹 استفاده همراه با
میتوانیم محاسبات را فقط روی رکوردهای موردنظر انجام دهیم:
در اینجا فقط دانشآموزانی که نمرهشان حداقل
⚠️ نکته مهم درباره
در بسیاری از توابع آماری SQLite، مقدارهای
مثلاً اگر داشته باشیم:
اما:
تعداد تمام رکوردها را میشمارد.
این موضوع را با:
میتوانیم مقایسه کنیم:
🧠 خلاصه
مثلاً:
یا:
یا:
🎯 تمرین
کد زیر را کامل کن تا تعداد دانشآموزان، مجموع نمرهها و میانگین نمرهها را نمایش دهد:
جای خالیها را با توابع مناسب پر کن.
پست ۱۹۲ از دوره جامع Python 🐍
محاسبه اطلاعات آماری با
COUNT، SUM و AVG در SQLiteتا اینجا بیشتر با دریافت و تغییر رکوردها کار کردیم.
اما در پروژههای واقعی گاهی لازم است بهجای نمایش تکتک رکوردها، روی دادهها محاسبه انجام دهیم.
SQLite چند تابع مهم برای این کار دارد:
COUNT
SUM
AVG
MIN
MAX
در این پست با سه مورد اول آشنا میشویم.
🔹
COUNTCOUNT برای شمارش رکوردها استفاده میشود.مثلاً تعداد دانشآموزان:
cursor.execute(
"SELECT COUNT(*) FROM students"
)
result = cursor.fetchone()
print(result[0])
اگر 10 دانشآموز داشته باشیم:
10
🔹 چرا
fetchone()؟چون
COUNT(*) فقط یک نتیجه برمیگرداند:(10,)
به همین دلیل:
result[0]
عدد
10 را از Tuple دریافت میکند.🔹 شمارش با شرط
میتوانیم فقط رکوردهایی را بشماریم که یک شرط مشخص دارند.
مثلاً تعداد دانشآموزانی که نمره حداقل
18 دارند:cursor.execute(
"SELECT COUNT(*) FROM students WHERE score >= ?",
(18,)
)
count = cursor.fetchone()[0]
print(count)
🔹
SUMSUM مجموع مقدارهای یک ستون را محاسبه میکند.مثلاً مجموع نمرهها:
cursor.execute(
"SELECT SUM(score) FROM students"
)
total_score = cursor.fetchone()[0]
print(total_score)
اگر نمرهها:
18
15
20
17
باشند:
70
🔹
AVGAVG میانگین مقدارهای یک ستون را محاسبه میکند.cursor.execute(
"SELECT AVG(score) FROM students"
)
average_score = cursor.fetchone()[0]
print(average_score)
برای نمرههای:
18
15
20
17
نتیجه:
17.5
🔥 ترکیب چند تابع
میتوانیم چند تابع آماری را در یک Query استفاده کنیم:
cursor.execute(
"""
SELECT
COUNT(*),
SUM(score),
AVG(score)
FROM students
"""
)
result = cursor.fetchone()
print("Count:", result[0])
print("Total:", result[1])
print("Average:", result[2])
مثلاً:
Count: 4
Total: 70
Average: 17.5
🔹 استفاده همراه با
WHEREمیتوانیم محاسبات را فقط روی رکوردهای موردنظر انجام دهیم:
cursor.execute(
"""
SELECT AVG(score)
FROM students
WHERE score >= ?
""",
(10,)
)
average = cursor.fetchone()[0]
print(average)
در اینجا فقط دانشآموزانی که نمرهشان حداقل
10 است در محاسبه میانگین قرار میگیرند.⚠️ نکته مهم درباره
NULLدر بسیاری از توابع آماری SQLite، مقدارهای
NULL در محاسبات عددی نادیده گرفته میشوند.مثلاً اگر داشته باشیم:
18
15
NULL
17
AVG(score) میانگین سه مقدار عددی را محاسبه میکند، نه چهار مقدار.اما:
COUNT(*)
تعداد تمام رکوردها را میشمارد.
این موضوع را با:
COUNT(score)
میتوانیم مقایسه کنیم:
cursor.execute(
"""
SELECT COUNT(*), COUNT(score)
FROM students
"""
)
result = cursor.fetchone()
print("All rows:", result[0])
print("Rows with score:", result[1])
COUNT(score) فقط مقدارهای غیر NULL را میشمارد.🧠 خلاصه
COUNT(*) → تعداد رکوردها
SUM() → مجموع
AVG() → میانگین
مثلاً:
SELECT COUNT(*) FROM students;
یا:
SELECT SUM(score) FROM students;
یا:
SELECT AVG(score) FROM students;
🎯 تمرین
کد زیر را کامل کن تا تعداد دانشآموزان، مجموع نمرهها و میانگین نمرهها را نمایش دهد:
import sqlite3
connection = sqlite3.connect("school.db")
cursor = connection.cursor()
cursor.execute(
"""
SELECT
COUNT(*),
______(score),
______(score)
FROM students
"""
)
result = cursor.fetchone()
print("Count:", result[0])
print("Total:", result[1])
print("Average:", result[2])
connection.close()
جای خالیها را با توابع مناسب پر کن.
پست ۱۹۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۳
پیدا کردن کمترین و بیشترین مقدار با
در پست قبل با توابع آماری:
آشنا شدیم.
حالا دو تابع بسیار کاربردی دیگر را یاد میگیریم:
🔹
تابع
مثلاً کمترین نمره:
اگر نمرهها اینها باشند:
خروجی:
🔹
تابع
خروجی:
🔹 استفاده با
مثل سایر توابع آماری، میتوانیم شرط هم داشته باشیم.
مثلاً بیشترین نمره بین دانشآموزانی که نمرهشان حداقل
🔥 استفاده از چند تابع با هم
میتوانیم کمترین، بیشترین و میانگین را در یک Query دریافت کنیم:
مثلاً:
🔹
این توابع میتوانند روی دادههای متنی هم استفاده شوند.
مثلاً:
در این حالت SQLite بر اساس ترتیب مقایسه رشتهها، مقدار حداقل و حداکثر را تعیین میکند.
⚠️ نکته مهم درباره
در محاسباتی مانند:
مقدارهای
مثلاً اگر:
داشته باشیم:
🔹 پیدا کردن رکورد مربوط به بیشترین نمره
اگر بخواهیم اطلاعات دانشآموزی که بیشترین نمره را دارد هم دریافت کنیم، میتوانیم از:
مثلاً:
اگر چند دانشآموز بالاترین نمره یکسان داشته باشند، همه آنها میتوانند برگردانده شوند.
🧠 خلاصه
مثلاً:
🎯 تمرین
کد زیر را کامل کن تا کمترین و بیشترین قیمت محصولات را پیدا کند:
توابع مناسب را جایگزین کن.
پست ۱۹۳ از دوره جامع Python 🐍
پیدا کردن کمترین و بیشترین مقدار با
MIN و MAX در SQLiteدر پست قبل با توابع آماری:
COUNT
SUM
AVG
آشنا شدیم.
حالا دو تابع بسیار کاربردی دیگر را یاد میگیریم:
MIN
MAX
🔹
MINتابع
MIN() کمترین مقدار یک ستون را برمیگرداند.مثلاً کمترین نمره:
cursor.execute(
"SELECT MIN(score) FROM students"
)
minimum = cursor.fetchone()[0]
print(minimum)
اگر نمرهها اینها باشند:
18
15
20
17
خروجی:
15
🔹
MAXتابع
MAX() بیشترین مقدار یک ستون را برمیگرداند.cursor.execute(
"SELECT MAX(score) FROM students"
)
maximum = cursor.fetchone()[0]
print(maximum)
خروجی:
20
🔹 استفاده با
WHEREمثل سایر توابع آماری، میتوانیم شرط هم داشته باشیم.
مثلاً بیشترین نمره بین دانشآموزانی که نمرهشان حداقل
10 است:cursor.execute(
"""
SELECT MAX(score)
FROM students
WHERE score >= ?
""",
(10,)
)
maximum = cursor.fetchone()[0]
print(maximum)
🔥 استفاده از چند تابع با هم
میتوانیم کمترین، بیشترین و میانگین را در یک Query دریافت کنیم:
cursor.execute(
"""
SELECT
MIN(score),
MAX(score),
AVG(score)
FROM students
"""
)
result = cursor.fetchone()
print("Minimum:", result[0])
print("Maximum:", result[1])
print("Average:", result[2])
مثلاً:
Minimum: 15
Maximum: 20
Average: 17.5
🔹
MIN و MAX فقط برای عدد نیستنداین توابع میتوانند روی دادههای متنی هم استفاده شوند.
مثلاً:
cursor.execute(
"SELECT MIN(name), MAX(name) FROM students"
)
result = cursor.fetchone()
print(result)
در این حالت SQLite بر اساس ترتیب مقایسه رشتهها، مقدار حداقل و حداکثر را تعیین میکند.
⚠️ نکته مهم درباره
NULLدر محاسباتی مانند:
MIN(score)
MAX(score)
AVG(score)
SUM(score)
مقدارهای
NULL در محاسبه نادیده گرفته میشوند.مثلاً اگر:
18
NULL
15
20
داشته باشیم:
MIN → 15
MAX → 20
AVG → میانگین 18، 15 و 20
🔹 پیدا کردن رکورد مربوط به بیشترین نمره
MAX(score) فقط خود مقدار را برمیگرداند.اگر بخواهیم اطلاعات دانشآموزی که بیشترین نمره را دارد هم دریافت کنیم، میتوانیم از:
cursor.execute(
"""
SELECT name, score
FROM students
WHERE score = (SELECT MAX(score) FROM students)
"""
)
students = cursor.fetchall()
for student in students:
print(student)
مثلاً:
('Reza', 20)اگر چند دانشآموز بالاترین نمره یکسان داشته باشند، همه آنها میتوانند برگردانده شوند.
🧠 خلاصه
COUNT() → تعداد
SUM() → مجموع
AVG() → میانگین
MIN() → کمترین مقدار
MAX() → بیشترین مقدار
مثلاً:
SELECT MIN(score), MAX(score)
FROM students;
🎯 تمرین
کد زیر را کامل کن تا کمترین و بیشترین قیمت محصولات را پیدا کند:
import sqlite3
connection = sqlite3.connect("shop.db")
cursor = connection.cursor()
cursor.execute(
"""
SELECT
______(price),
______(price)
FROM products
"""
)
result = cursor.fetchone()
print("Minimum:", result[0])
print("Maximum:", result[1])
connection.close()
توابع مناسب را جایگزین کن.
پست ۱۹۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۴
گروهبندی دادهها با
تا اینجا با توابعی مثل:
کار کردیم.
اما گاهی نمیخواهیم این محاسبات را روی کل جدول انجام دهیم؛ بلکه میخواهیم دادهها را بر اساس یک ستون گروهبندی کنیم.
برای این کار از:
استفاده میکنیم.
🔹
فرض کنیم جدول
اگر بخواهیم میانگین نمره هر کلاس را محاسبه کنیم:
خروجی:
SQLite ابتدا رکوردها را بر اساس
🔹 تعداد اعضای هر گروه
میتوانیم از
مثلاً تعداد دانشآموزان هر کلاس:
خروجی:
🔹 مجموع هر گروه با
مثلاً مجموع نمرههای هر کلاس:
خروجی:
🔥 ترکیب چند تابع
میتوانیم چند محاسبه را همزمان انجام دهیم:
هر ردیف نتیجه شامل اطلاعات آماری یک کلاس خواهد بود.
🔹
میتوانیم بیشتر از یک ستون را هم گروهبندی کنیم.
مثلاً:
در این حالت گروهها بر اساس ترکیب:
تشکیل میشوند.
🔹 تفاوت
این دو وظیفه متفاوتی دارند.
اما:
رکوردهای باقیمانده را گروهبندی میکند.
مثلاً:
ترتیب منطقی:
یعنی ابتدا رکوردهای نامعتبر حذف میشوند، سپس دادههای باقیمانده گروهبندی و محاسبه میشوند.
⚠️ نکته مهم
وقتی از
نه اینکه یک ستون نامرتبط را بدون دلیل وارد نتیجه کنیم.
🧠 خلاصه
مثلاً:
یعنی:
🎯 تمرین
جدول
کد را کامل کن تا میانگین قیمت هر دستهبندی نمایش داده شود:
دو جای خالی را کامل کن.
پست ۱۹۴ از دوره جامع Python 🐍
گروهبندی دادهها با
GROUP BY در SQLiteتا اینجا با توابعی مثل:
COUNT()
SUM()
AVG()
MIN()
MAX()
کار کردیم.
اما گاهی نمیخواهیم این محاسبات را روی کل جدول انجام دهیم؛ بلکه میخواهیم دادهها را بر اساس یک ستون گروهبندی کنیم.
برای این کار از:
GROUP BY
استفاده میکنیم.
🔹
GROUP BY چیست؟فرض کنیم جدول
students شامل این اطلاعات باشد:name | class | score
Ali | Python | 18
Sara | Python | 20
Reza | Django | 15
Mina | Django | 17
اگر بخواهیم میانگین نمره هر کلاس را محاسبه کنیم:
cursor.execute(
"""
SELECT class, AVG(score)
FROM students
GROUP BY class
"""
)
results = cursor.fetchall()
for row in results:
print(row)
خروجی:
('Django', 16.0)
('Python', 19.0)SQLite ابتدا رکوردها را بر اساس
class گروهبندی میکند و سپس AVG() را برای هر گروه محاسبه میکند.🔹 تعداد اعضای هر گروه
میتوانیم از
COUNT() هم استفاده کنیم.مثلاً تعداد دانشآموزان هر کلاس:
cursor.execute(
"""
SELECT class, COUNT(*)
FROM students
GROUP BY class
"""
)
results = cursor.fetchall()
for row in results:
print(row)
خروجی:
('Django', 2)
('Python', 2)🔹 مجموع هر گروه با
SUM()مثلاً مجموع نمرههای هر کلاس:
cursor.execute(
"""
SELECT class, SUM(score)
FROM students
GROUP BY class
"""
)
results = cursor.fetchall()
for row in results:
print(row)
خروجی:
('Django', 32)
('Python', 38)🔥 ترکیب چند تابع
میتوانیم چند محاسبه را همزمان انجام دهیم:
cursor.execute(
"""
SELECT
class,
COUNT(*),
AVG(score),
MIN(score),
MAX(score)
FROM students
GROUP BY class
"""
)
results = cursor.fetchall()
for row in results:
print(row)
هر ردیف نتیجه شامل اطلاعات آماری یک کلاس خواهد بود.
🔹
GROUP BY با چند ستونمیتوانیم بیشتر از یک ستون را هم گروهبندی کنیم.
مثلاً:
cursor.execute(
"""
SELECT class, gender, COUNT(*)
FROM students
GROUP BY class, gender
"""
)
در این حالت گروهها بر اساس ترکیب:
class + gender
تشکیل میشوند.
🔹 تفاوت
WHERE و GROUP BYاین دو وظیفه متفاوتی دارند.
WHERE ابتدا رکوردها را فیلتر میکند:WHERE score >= 10
اما:
GROUP BY class
رکوردهای باقیمانده را گروهبندی میکند.
مثلاً:
cursor.execute(
"""
SELECT class, AVG(score)
FROM students
WHERE score >= ?
GROUP BY class
""",
(10,)
)
ترتیب منطقی:
FROM
↓
WHERE
↓
GROUP BY
↓
AVG()
یعنی ابتدا رکوردهای نامعتبر حذف میشوند، سپس دادههای باقیمانده گروهبندی و محاسبه میشوند.
⚠️ نکته مهم
وقتی از
GROUP BY استفاده میکنیم، معمولاً ستون گروهبندیشده را همراه با یک تابع تجمیعی (Aggregate Function) انتخاب میکنیم:SELECT class, AVG(score)
FROM students
GROUP BY class;
نه اینکه یک ستون نامرتبط را بدون دلیل وارد نتیجه کنیم.
🧠 خلاصه
GROUP BY → گروهبندی رکوردها
COUNT() → تعداد هر گروه
SUM() → مجموع هر گروه
AVG() → میانگین هر گروه
MIN() → کمترین مقدار هر گروه
MAX() → بیشترین مقدار هر گروه
مثلاً:
SELECT class, AVG(score)
FROM students
GROUP BY class;
یعنی:
میانگین نمره را برای هر کلاس جداگانه محاسبه کن.
🎯 تمرین
جدول
products را در نظر بگیر:name | category | price
Laptop | PC | 1200
Mouse | PC | 50
Phone | Mobile | 800
Tablet | Mobile | 500
کد را کامل کن تا میانگین قیمت هر دستهبندی نمایش داده شود:
cursor.execute(
"""
SELECT category, ______(price)
FROM products
GROUP BY ______
"""
)
دو جای خالی را کامل کن.
پست ۱۹۴ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۵
فیلتر کردن گروهها با
در پست قبل با
حالا میخواهیم فقط گروههایی را که یک شرط مشخص دارند نمایش دهیم.
برای این کار از:
استفاده میکنیم.
🔹 تفاوت
این تفاوت بسیار مهم است:
مثلاً:
قبل از گروهبندی روی رکوردها اعمال میشود.
اما:
بعد از گروهبندی، گروهها را بررسی میکند.
🔹 مثال ساده
فرض کنیم:
میخواهیم فقط کلاسهایی را نمایش دهیم که میانگین نمرهشان حداقل 15 باشد:
نتیجه:
کلاس
است.
🔹 استفاده از
مثلاً میخواهیم فقط دستهبندیهایی را ببینیم که حداقل ۲ محصول دارند:
در اینجا:
🔥 ترکیب
میتوانیم هر دو را در یک Query داشته باشیم.
مثلاً:
ترتیب منطقی:
یعنی:
رکوردها انتخاب میشوند.
رکوردها فیلتر میشوند.
رکوردهای باقیمانده گروهبندی میشوند.
گروهها فیلتر میشوند.
نتیجه نهایی برگردانده میشود.
⚠️ اشتباه رایج
اگر بخواهیم بر اساس یک Aggregate Function مثل
❌ نادرست:
✅ درست:
چون
🔹
در بعضی Queryها میتوان
🧠 خلاصه
مثلاً:
🎯 تمرین
کد زیر را کامل کن تا فقط دستهبندیهایی نمایش داده شوند که:
حداقل ۲ محصول دارند.
میانگین قیمتشان حداقل 500 است.
مقادیر مناسب را جایگزین کن.
پست ۱۹۵ از دوره جامع Python 🐍
فیلتر کردن گروهها با
HAVING در SQLiteدر پست قبل با
GROUP BY یاد گرفتیم دادهها را گروهبندی کنیم.حالا میخواهیم فقط گروههایی را که یک شرط مشخص دارند نمایش دهیم.
برای این کار از:
HAVING
استفاده میکنیم.
🔹 تفاوت
WHERE و HAVINGاین تفاوت بسیار مهم است:
WHERE → فیلتر کردن رکوردها
HAVING → فیلتر کردن گروهها
مثلاً:
WHERE score >= 10
قبل از گروهبندی روی رکوردها اعمال میشود.
اما:
HAVING AVG(score) >= 15
بعد از گروهبندی، گروهها را بررسی میکند.
🔹 مثال ساده
فرض کنیم:
class | score
Python | 18
Python | 20
Django | 10
Django | 12
Flask | 17
Flask | 19
میخواهیم فقط کلاسهایی را نمایش دهیم که میانگین نمرهشان حداقل 15 باشد:
cursor.execute(
"""
SELECT class, AVG(score)
FROM students
GROUP BY class
HAVING AVG(score) >= ?
""",
(15,)
)
results = cursor.fetchall()
for row in results:
print(row)
نتیجه:
('Python', 19.0)
('Flask', 18.0)کلاس
Django حذف میشود چون میانگین آن:11.0
است.
🔹 استفاده از
COUNT() با HAVINGمثلاً میخواهیم فقط دستهبندیهایی را ببینیم که حداقل ۲ محصول دارند:
cursor.execute(
"""
SELECT category, COUNT(*)
FROM products
GROUP BY category
HAVING COUNT(*) >= ?
""",
(2,)
)
در اینجا:
GROUP BY → محصولات را بر اساس category گروهبندی میکند
COUNT() → تعداد محصولات هر گروه
HAVING → فقط گروههای دارای حداقل ۲ محصول
🔥 ترکیب
WHERE و HAVINGمیتوانیم هر دو را در یک Query داشته باشیم.
مثلاً:
ابتدا محصولاتی که قیمتشان حداقل 100 است را انتخاب کن؛ سپس فقط دستهبندیهایی را نمایش بده که میانگین قیمتشان حداقل 500 باشد.
cursor.execute(
"""
SELECT category, AVG(price)
FROM products
WHERE price >= ?
GROUP BY category
HAVING AVG(price) >= ?
""",
(100, 500)
)
ترتیب منطقی:
FROM
↓
WHERE
↓
GROUP BY
↓
HAVING
↓
SELECT
یعنی:
رکوردها انتخاب میشوند.
رکوردها فیلتر میشوند.
رکوردهای باقیمانده گروهبندی میشوند.
گروهها فیلتر میشوند.
نتیجه نهایی برگردانده میشود.
⚠️ اشتباه رایج
اگر بخواهیم بر اساس یک Aggregate Function مثل
AVG() گروهها را فیلتر کنیم، نمیتوانیم آن شرط را در WHERE قرار دهیم:❌ نادرست:
WHERE AVG(score) >= 15
✅ درست:
HAVING AVG(score) >= 15
چون
AVG() بعد از تشکیل گروهها محاسبه میشود.🔹
HAVING بدون GROUP BYدر بعضی Queryها میتوان
HAVING را بدون GROUP BY هم استفاده کرد، اما برای این مرحله بهتر است تمرکزمان روی الگوی رایج باشد:GROUP BY ...
HAVING ...
🧠 خلاصه
WHERE → فیلتر رکوردها
GROUP BY → ساخت گروهها
HAVING → فیلتر گروهها
مثلاً:
SELECT category, AVG(price)
FROM products
WHERE price >= 100
GROUP BY category
HAVING AVG(price) >= 500;
🎯 تمرین
کد زیر را کامل کن تا فقط دستهبندیهایی نمایش داده شوند که:
حداقل ۲ محصول دارند.
میانگین قیمتشان حداقل 500 است.
cursor.execute(
"""
SELECT category, COUNT(*), AVG(price)
FROM products
GROUP BY category
HAVING COUNT(*) >= ?
AND AVG(price) >= ?
""",
(______, ______)
)
مقادیر مناسب را جایگزین کن.
پست ۱۹۵ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۶
اتصال چند جدول در SQLite با
تا اینجا بیشتر با یک جدول کار کردیم.
اما در پروژههای واقعی معمولاً اطلاعات را در چند جدول مرتبط نگهداری میکنیم.
مثلاً:
و بین آنها یک ارتباط وجود دارد.
برای ترکیب اطلاعات این جدولها از:
استفاده میکنیم.
🔹 مثال
فرض کنیم جدول
و جدول
در جدول
🔹
رایجترین نوع JOIN،
میخواهیم نام دانشآموز و نام دوره او را در یک نتیجه ببینیم:
خروجی:
🔹
این بخش:
به SQLite میگوید کدام رکوردهای دو جدول به یکدیگر مرتبط هستند.
یعنی:
🔹 چرا از نام جدول استفاده کردیم؟
هر دو جدول ممکن است ستونی به نام
مثلاً:
با نوشتن نام جدول، مشخص میکنیم دقیقاً کدام ستون را میخواهیم.
🔹 استفاده از Alias
برای Queryهای طولانی میتوانیم نام کوتاهتری برای جدولها تعیین کنیم:
اینجا:
پس:
یعنی:
🔥 ترکیب
میتوانیم بعد از اتصال جدولها، نتیجه را فیلتر کنیم.
مثلاً فقط دانشآموزان دوره Python:
خروجی:
🔹
حتی میتوانیم چند جدول را به هم متصل کنیم.
مثلاً:
و Query:
در این حالت اطلاعات از سه جدول ترکیب میشوند.
⚠️ نکته مهم
در
مثلاً اگر دانشآموزی
در پست بعدی سراغ نوع مهم دیگری از JOIN یعنی
🧠 خلاصه
ساختار کلی:
🎯 تمرین
دو جدول زیر را در نظر بگیر:
کد را کامل کن تا نام کاربر و نام شهر او نمایش داده شود:
دو جای خالی را طوری کامل کن که رابطه بین
پست ۱۹۶ از دوره جامع Python 🐍
اتصال چند جدول در SQLite با
JOINتا اینجا بیشتر با یک جدول کار کردیم.
اما در پروژههای واقعی معمولاً اطلاعات را در چند جدول مرتبط نگهداری میکنیم.
مثلاً:
students
courses
و بین آنها یک ارتباط وجود دارد.
برای ترکیب اطلاعات این جدولها از:
JOIN
استفاده میکنیم.
🔹 مثال
فرض کنیم جدول
students:id | name | course_id
1 | Ali | 10
2 | Sara | 20
3 | Reza | 10
و جدول
courses:id | name
10 | Python
20 | Django
در جدول
students، ستون course_id به courses.id اشاره میکند.🔹
INNER JOINرایجترین نوع JOIN،
INNER JOIN است.میخواهیم نام دانشآموز و نام دوره او را در یک نتیجه ببینیم:
cursor.execute(
"""
SELECT students.name, courses.name
FROM students
INNER JOIN courses
ON students.course_id = courses.id
"""
)
results = cursor.fetchall()
for row in results:
print(row)
خروجی:
('Ali', 'Python')
('Sara', 'Django')
('Reza', 'Python')🔹
ON چه کاری انجام میدهد؟این بخش:
ON students.course_id = courses.id
به SQLite میگوید کدام رکوردهای دو جدول به یکدیگر مرتبط هستند.
یعنی:
students.course_id
↓
courses.id
🔹 چرا از نام جدول استفاده کردیم؟
هر دو جدول ممکن است ستونی به نام
id یا name داشته باشند.مثلاً:
students.name
courses.name
با نوشتن نام جدول، مشخص میکنیم دقیقاً کدام ستون را میخواهیم.
🔹 استفاده از Alias
برای Queryهای طولانی میتوانیم نام کوتاهتری برای جدولها تعیین کنیم:
cursor.execute(
"""
SELECT s.name, c.name
FROM students AS s
INNER JOIN courses AS c
ON s.course_id = c.id
"""
)
اینجا:
s → students
c → courses
پس:
s.name
یعنی:
students.name
🔥 ترکیب
JOIN با WHEREمیتوانیم بعد از اتصال جدولها، نتیجه را فیلتر کنیم.
مثلاً فقط دانشآموزان دوره Python:
cursor.execute(
"""
SELECT s.name, c.name
FROM students AS s
INNER JOIN courses AS c
ON s.course_id = c.id
WHERE c.name = ?
""",
("Python",)
)
results = cursor.fetchall()
for row in results:
print(row)
خروجی:
('Ali', 'Python')
('Reza', 'Python')🔹
JOIN با سه جدولحتی میتوانیم چند جدول را به هم متصل کنیم.
مثلاً:
students
courses
teachers
و Query:
cursor.execute(
"""
SELECT s.name, c.name, t.name
FROM students AS s
INNER JOIN courses AS c
ON s.course_id = c.id
INNER JOIN teachers AS t
ON c.teacher_id = t.id
"""
)
در این حالت اطلاعات از سه جدول ترکیب میشوند.
⚠️ نکته مهم
در
INNER JOIN فقط رکوردهایی برگردانده میشوند که در هر دو جدول تطابق داشته باشند.مثلاً اگر دانشآموزی
course_id داشته باشد که در جدول courses وجود نداشته باشد، آن دانشآموز در نتیجه INNER JOIN نمایش داده نمیشود.در پست بعدی سراغ نوع مهم دیگری از JOIN یعنی
LEFT JOIN میرویم.🧠 خلاصه
JOIN → اتصال جدولها
ON → مشخص کردن رابطه
INNER JOIN → فقط رکوردهای دارای تطابق
AS → ساخت Alias برای جدول
ساختار کلی:
SELECT ...
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
🎯 تمرین
دو جدول زیر را در نظر بگیر:
users
id | name | city_id
cities
id | name
کد را کامل کن تا نام کاربر و نام شهر او نمایش داده شود:
cursor.execute(
"""
SELECT u.name, c.name
FROM users AS u
INNER JOIN cities AS c
ON u.______ = c.______
"""
)
دو جای خالی را طوری کامل کن که رابطه بین
users و cities برقرار شود.پست ۱۹۶ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۷
اتصال جدولها با
در پست قبل با
اما گاهی میخواهیم:
برای این کار از:
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم جدول
و جدول
حالا:
نتیجه:
🔹 چرا
چون در
اینجا:
جدول
پس حتی اگر:
باشد، رکورد
چون شهر متناظر وجود ندارد، ستونهای جدول
خواهند داشت.
🔥 مقایسه
با
نتیجه:
اما با:
نتیجه:
پس:
🔹 پیدا کردن رکوردهای بدون تطابق
یکی از کاربردهای بسیار مهم
مثلاً میخواهیم کاربرانی را پیدا کنیم که شهر معتبری برایشان ثبت نشده است:
نتیجه:
اینجا:
یعنی در جدول
🔹
میتوانیم نتیجه را با
در این حالت فقط کاربرانی که شهرشان
⚠️ توجه کن که قرار دادن شرط روی جدول سمت راست در
🔹 شرط داخل
گاهی میخواهیم ویژگی
در این حالت تمام کاربران جدول
🧠 خلاصه
ساختار:
و برای پیدا کردن موارد بدون تطابق:
🎯 تمرین
دو جدول زیر را در نظر بگیر:
کدی بنویس که تمام سفارشها را نمایش دهد و در کنار هر سفارش، نام کاربر مربوطه را هم نشان دهد.
اگر یک سفارش
راهنما:
پست ۱۹۷ از دوره جامع Python 🐍
اتصال جدولها با
LEFT JOIN در SQLiteدر پست قبل با
INNER JOIN آشنا شدیم.INNER JOIN فقط رکوردهایی را برمیگرداند که در هر دو جدول تطابق داشته باشند.اما گاهی میخواهیم:
تمام رکوردهای جدول اصلی را نگه داریم، حتی اگر در جدول دوم تطابقی وجود نداشته باشد.
برای این کار از:
LEFT JOIN
استفاده میکنیم.
🔹 مثال ساده
فرض کنیم جدول
users:id | name | city_id
1 | Ali | 10
2 | Sara | 20
3 | Reza | NULL
و جدول
cities:id | name
10 | Tehran
20 | Baku
30 | Tabriz
حالا:
cursor.execute(
"""
SELECT u.name, c.name
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id
"""
)
results = cursor.fetchall()
for row in results:
print(row)
نتیجه:
('Ali', 'Tehran')
('Sara', 'Baku')
('Reza', None)🔹 چرا
Reza هم نمایش داده شد؟چون در
LEFT JOIN، تمام رکوردهای جدول سمت چپ حفظ میشوند.اینجا:
FROM users AS u
جدول
users سمت چپ است.پس حتی اگر:
u.city_id → NULL
باشد، رکورد
Reza حذف نمیشود.چون شهر متناظر وجود ندارد، ستونهای جدول
cities مقدار:None
خواهند داشت.
🔥 مقایسه
INNER JOIN و LEFT JOINبا
INNER JOIN:FROM users AS u
INNER JOIN cities AS c
ON u.city_id = c.id
نتیجه:
Ali → Tehran
Sara → Baku
Reza نمایش داده نمیشود.اما با:
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id
نتیجه:
Ali → Tehran
Sara → Baku
Reza → None
پس:
INNER JOIN → فقط رکوردهای دارای تطابق
LEFT JOIN → تمام رکوردهای جدول چپ + تطابقهای جدول راست
🔹 پیدا کردن رکوردهای بدون تطابق
یکی از کاربردهای بسیار مهم
LEFT JOIN پیدا کردن رکوردهایی است که رکورد مرتبط ندارند.مثلاً میخواهیم کاربرانی را پیدا کنیم که شهر معتبری برایشان ثبت نشده است:
cursor.execute(
"""
SELECT u.name
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id
WHERE c.id IS NULL
"""
)
users = cursor.fetchall()
for user in users:
print(user)
نتیجه:
('Reza',)اینجا:
WHERE c.id IS NULL
یعنی در جدول
cities رکورد متناظری پیدا نشده است.🔹
LEFT JOIN با شرطمیتوانیم نتیجه را با
WHERE فیلتر کنیم:cursor.execute(
"""
SELECT u.name, c.name
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id
WHERE c.name = ?
""",
("Baku",)
)
در این حالت فقط کاربرانی که شهرشان
Baku است برگردانده میشوند.⚠️ توجه کن که قرار دادن شرط روی جدول سمت راست در
WHERE میتواند باعث شود رفتار Query شبیه INNER JOIN شود، چون رکوردهای دارای NULL در ستونهای جدول راست حذف میشوند.🔹 شرط داخل
ONگاهی میخواهیم ویژگی
LEFT JOIN را حفظ کنیم و شرط مربوط به جدول دوم را داخل ON قرار دهیم:cursor.execute(
"""
SELECT u.name, c.name
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id
AND c.name = ?
""",
("Baku",)
)
در این حالت تمام کاربران جدول
users همچنان حفظ میشوند.🧠 خلاصه
INNER JOIN
↓
فقط رکوردهای دارای تطابق
LEFT JOIN
↓
تمام رکوردهای جدول چپ
+
رکوردهای مطابق از جدول راست
ساختار:
SELECT ...
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;
و برای پیدا کردن موارد بدون تطابق:
WHERE table2.id IS NULL
🎯 تمرین
دو جدول زیر را در نظر بگیر:
orders
id | user_id | amount
users
id | name
کدی بنویس که تمام سفارشها را نمایش دهد و در کنار هر سفارش، نام کاربر مربوطه را هم نشان دهد.
اگر یک سفارش
user_id نامعتبر داشته باشد، آن سفارش باید همچنان نمایش داده شود و نام کاربر None باشد.راهنما:
cursor.execute(
"""
SELECT o.id, o.amount, u.name
FROM orders AS o
______ JOIN users AS u
ON o.user_id = u.id
"""
)
پست ۱۹۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۸
اتصال چند جدول و انواع
در پستهای قبل با
حالا میخواهیم تفاوت انواع مهم
🔹
فقط رکوردهایی را برمیگرداند که در دو جدول تطابق داشته باشند.
مثلاً:
اگر کاربری شهر معتبر نداشته باشد، در نتیجه نمایش داده نمیشود.
🔹
تمام رکوردهای جدول سمت چپ را نگه میدارد:
اگر شهر متناظر پیدا نشود:
🔹 چند
فرض کنیم سه جدول داریم:
ساختار:
مثلاً:
در این Query اطلاعات سه جدول با هم ترکیب میشوند.
🔹 چرا
میتوانیم Query را به شکل زیر تصور کنیم:
هر
🔥 ترکیب
مثلاً میخواهیم فقط سفارشهای یک کاربر خاص را ببینیم:
اینجا:
🔹
مثلاً سفارشها را بر اساس مبلغ، از بیشترین به کمترین مرتب کنیم:
🔹
میتوانیم اطلاعات چند جدول را ابتدا متصل کنیم و سپس آنها را گروهبندی کنیم.
مثلاً مجموع سفارشهای هر کاربر:
مثلاً:
🔹
در SQL استاندارد، انواع دیگری مانند:
هم وجود دارند.
اما باید تفاوت نسخه SQLite را در نظر بگیریم و در طراحی Queryها صرفاً بر اساس SQL عمومی فرض نکنیم که تمام رفتارها در همه نسخهها یکسان است.
برای این دوره فعلاً تمرکز اصلی ما روی:
است؛ چون این دو در پروژههای SQLite بسیار پرکاربرد هستند.
⚠️ نکته مهم: نام ستونها
وقتی چند جدول ستونهای مشابه دارند، بهتر است همیشه از Alias استفاده کنیم:
بهجای اینکه Query را مبهم بنویسیم.
Alias باعث میشود Query خواناتر و احتمال اشتباه کمتر شود:
🧠 خلاصه
و میتوانیم چند JOIN را پشت سر هم استفاده کنیم:
سپس آن را با:
ترکیب کنیم.
🎯 تمرین
سه جدول زیر را در نظر بگیر:
کد را کامل کن تا نام کاربر، نام محصول و مبلغ سفارش نمایش داده شود:
هر دو جای خالی را با نوع مناسب
پست ۱۹۸ از دوره جامع Python 🐍
اتصال چند جدول و انواع
JOIN در SQLiteدر پستهای قبل با
INNER JOIN و LEFT JOIN آشنا شدیم.حالا میخواهیم تفاوت انواع مهم
JOIN را بهتر بشناسیم و ببینیم چطور میتوانیم چند جدول را همزمان به هم متصل کنیم.🔹
INNER JOINفقط رکوردهایی را برمیگرداند که در دو جدول تطابق داشته باشند.
مثلاً:
SELECT u.name, c.name
FROM users AS u
INNER JOIN cities AS c
ON u.city_id = c.id;
اگر کاربری شهر معتبر نداشته باشد، در نتیجه نمایش داده نمیشود.
🔹
LEFT JOINتمام رکوردهای جدول سمت چپ را نگه میدارد:
SELECT u.name, c.name
FROM users AS u
LEFT JOIN cities AS c
ON u.city_id = c.id;
اگر شهر متناظر پیدا نشود:
user → name
city → None
🔹 چند
JOIN در یک Queryفرض کنیم سه جدول داریم:
users
orders
products
ساختار:
users
↓
orders
↓
products
مثلاً:
cursor.execute(
"""
SELECT
u.name,
p.name,
o.amount
FROM users AS u
INNER JOIN orders AS o
ON u.id = o.user_id
INNER JOIN products AS p
ON o.product_id = p.id
"""
)
results = cursor.fetchall()
for row in results:
print(row)
در این Query اطلاعات سه جدول با هم ترکیب میشوند.
🔹 چرا
JOINها را مرحلهبهمرحله مینویسیم؟میتوانیم Query را به شکل زیر تصور کنیم:
users
↓
JOIN orders
↓
JOIN products
↓
نتیجه نهایی
هر
JOIN یک جدول دیگر را به نتیجه اضافه میکند.🔥 ترکیب
JOIN با WHEREمثلاً میخواهیم فقط سفارشهای یک کاربر خاص را ببینیم:
cursor.execute(
"""
SELECT
u.name,
p.name,
o.amount
FROM users AS u
INNER JOIN orders AS o
ON u.id = o.user_id
INNER JOIN products AS p
ON o.product_id = p.id
WHERE u.id = ?
""",
(1,)
)
اینجا:
JOIN → جدولها را متصل میکند
WHERE → نتیجه را فیلتر میکند
🔹
JOIN با ORDER BYمثلاً سفارشها را بر اساس مبلغ، از بیشترین به کمترین مرتب کنیم:
cursor.execute(
"""
SELECT
u.name,
p.name,
o.amount
FROM users AS u
INNER JOIN orders AS o
ON u.id = o.user_id
INNER JOIN products AS p
ON o.product_id = p.id
ORDER BY o.amount DESC
"""
)
🔹
JOIN با GROUP BYمیتوانیم اطلاعات چند جدول را ابتدا متصل کنیم و سپس آنها را گروهبندی کنیم.
مثلاً مجموع سفارشهای هر کاربر:
cursor.execute(
"""
SELECT
u.name,
SUM(o.amount)
FROM users AS u
INNER JOIN orders AS o
ON u.id = o.user_id
GROUP BY u.id, u.name
"""
)
results = cursor.fetchall()
for row in results:
print(row)
مثلاً:
Ali → 1500
Sara → 800
Reza → 420
🔹
RIGHT JOIN و FULL OUTER JOINدر SQL استاندارد، انواع دیگری مانند:
RIGHT JOIN
FULL OUTER JOIN
هم وجود دارند.
اما باید تفاوت نسخه SQLite را در نظر بگیریم و در طراحی Queryها صرفاً بر اساس SQL عمومی فرض نکنیم که تمام رفتارها در همه نسخهها یکسان است.
برای این دوره فعلاً تمرکز اصلی ما روی:
INNER JOIN
LEFT JOIN
است؛ چون این دو در پروژههای SQLite بسیار پرکاربرد هستند.
⚠️ نکته مهم: نام ستونها
وقتی چند جدول ستونهای مشابه دارند، بهتر است همیشه از Alias استفاده کنیم:
SELECT
u.id,
u.name,
o.id,
o.amount
بهجای اینکه Query را مبهم بنویسیم.
Alias باعث میشود Query خواناتر و احتمال اشتباه کمتر شود:
u → users
o → orders
p → products
🧠 خلاصه
INNER JOIN → فقط رکوردهای دارای تطابق
LEFT JOIN → تمام رکوردهای جدول چپ + تطابقهای جدول راست
و میتوانیم چند JOIN را پشت سر هم استفاده کنیم:
FROM users AS u
JOIN orders AS o
ON u.id = o.user_id
JOIN products AS p
ON o.product_id = p.id
سپس آن را با:
WHERE
GROUP BY
HAVING
ORDER BY
ترکیب کنیم.
🎯 تمرین
سه جدول زیر را در نظر بگیر:
users
id | name
orders
id | user_id | product_id
products
id | name | price
کد را کامل کن تا نام کاربر، نام محصول و مبلغ سفارش نمایش داده شود:
cursor.execute(
"""
SELECT
u.name,
p.name,
o.amount
FROM users AS u
______ JOIN orders AS o
ON u.id = o.user_id
______ JOIN products AS p
ON o.product_id = p.id
"""
)
هر دو جای خالی را با نوع مناسب
JOIN کامل کن.پست ۱۹۸ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۹۹
محدود کردن نتیجه Query با
تا اینجا با
اما اگر بخواهیم از یک نقطه مشخص شروع کنیم و چند رکورد را رد کنیم، از:
استفاده میکنیم.
🔹
فرض کنیم جدول
اگر بنویسیم:
دو رکورد اول نادیده گرفته میشوند:
و نتیجه:
خواهد بود.
🔹 ترکیب
ساختار کلی:
مثلاً:
یعنی:
🔥 کاربرد مهم: Pagination
مثلاً اگر در هر صفحه 10 رکورد نمایش دهیم:
فرمول:
مثلاً برای صفحه 3:
پس:
🔹 پیادهسازی با Python
در این مثال:
پس رکوردهای صفحه سوم دریافت میشوند.
⚠️
برای Pagination بهتر است ترتیب نتایج را مشخص کنیم:
چون بدون ترتیب مشخص، نباید روی ترتیب طبیعی بازگشت رکوردها حساب کنیم.
پس بهتر است بنویسیم:
🔹
در SQLite میتوان
مثلاً:
یعنی:
اما در پروژههای معمول، استفاده از:
برای Pagination رایجتر و خواناتر است.
🧠 خلاصه
مثلاً:
یعنی:
و برای صفحهبندی:
🎯 تمرین
کد زیر را کامل کن تا صفحه چهارم را با 5 رکورد در هر صفحه دریافت کند:
مقدار مناسب را جایگزین کن.
پست ۱۹۹ از دوره جامع Python 🐍
محدود کردن نتیجه Query با
OFFSET در SQLiteتا اینجا با
LIMIT آشنا شدیم.LIMIT مشخص میکند چند رکورد برگردانده شود.اما اگر بخواهیم از یک نقطه مشخص شروع کنیم و چند رکورد را رد کنیم، از:
OFFSET
استفاده میکنیم.
🔹
OFFSET چیست؟فرض کنیم جدول
students این اطلاعات را داشته باشد:id | name
1 | Ali
2 | Sara
3 | Reza
4 | Mina
5 | Arman
اگر بنویسیم:
cursor.execute(
"""
SELECT *
FROM students
ORDER BY id
LIMIT 2 OFFSET 2
"""
)
دو رکورد اول نادیده گرفته میشوند:
Ali
Sara
و نتیجه:
Reza
Mina
خواهد بود.
🔹 ترکیب
LIMIT و OFFSETساختار کلی:
SELECT ...
FROM table
LIMIT number
OFFSET number;
مثلاً:
LIMIT 10 OFFSET 20
یعنی:
۲۰ رکورد اول را رد کن و سپس حداکثر ۱۰ رکورد برگردان.
🔥 کاربرد مهم: Pagination
LIMIT و OFFSET در ساخت صفحهبندی (Pagination) بسیار کاربردی هستند.مثلاً اگر در هر صفحه 10 رکورد نمایش دهیم:
Page 1 → OFFSET 0
Page 2 → OFFSET 10
Page 3 → OFFSET 20
Page 4 → OFFSET 30
فرمول:
OFFSET = (page - 1) × page_size
مثلاً برای صفحه 3:
(3 - 1) × 10 = 20
پس:
LIMIT 10 OFFSET 20
🔹 پیادهسازی با Python
page = 3
page_size = 10
offset = (page - 1) * page_size
cursor.execute(
"""
SELECT *
FROM students
ORDER BY id
LIMIT ? OFFSET ?
""",
(page_size, offset)
)
students = cursor.fetchall()
for student in students:
print(student)
در این مثال:
page → 3
page_size → 10
offset → 20
پس رکوردهای صفحه سوم دریافت میشوند.
⚠️
ORDER BY مهم استبرای Pagination بهتر است ترتیب نتایج را مشخص کنیم:
ORDER BY id
چون بدون ترتیب مشخص، نباید روی ترتیب طبیعی بازگشت رکوردها حساب کنیم.
پس بهتر است بنویسیم:
SELECT *
FROM students
ORDER BY id
LIMIT ? OFFSET ?;
🔹
OFFSET بهتنهاییدر SQLite میتوان
OFFSET را همراه LIMIT استفاده کرد.مثلاً:
LIMIT -1 OFFSET 5
یعنی:
پنج رکورد اول را رد کن و بقیه را برگردان.
اما در پروژههای معمول، استفاده از:
LIMIT + OFFSET
برای Pagination رایجتر و خواناتر است.
🧠 خلاصه
LIMIT → تعداد رکوردها
OFFSET → تعداد رکوردهایی که از ابتدای نتیجه رد میشوند
مثلاً:
LIMIT 10 OFFSET 20
یعنی:
۲۰ رکورد اول → رد
۱۰ رکورد بعدی → نتیجه
و برای صفحهبندی:
OFFSET = (page - 1) × page_size
🎯 تمرین
کد زیر را کامل کن تا صفحه چهارم را با 5 رکورد در هر صفحه دریافت کند:
page = 4
page_size = 5
offset = (page - 1) * page_size
cursor.execute(
"""
SELECT *
FROM students
ORDER BY id
LIMIT ? OFFSET ?
""",
(page_size, ______)
)
مقدار مناسب را جایگزین کن.
پست ۱۹۹ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۰
محدودیتهای جدول در SQLite |
تا اینجا یاد گرفتیم چطور دادهها را در SQLite ذخیره، جستوجو، تغییر و حذف کنیم.
اما در یک Database واقعی فقط ذخیره کردن داده کافی نیست؛ باید مشخص کنیم چه دادهای مجاز است وارد جدول شود.
برای این کار از Constraintها استفاده میکنیم.
در این پست با دو Constraint مهم آشنا میشویم:
🔹
مثلاً:
اینجا:
هر رکورد باید شناسه منحصربهفرد داشته باشد.
مثلاً:
🔹 جلوگیری از شناسه تکراری
اگر بخواهیم دوباره
SQLite خطایی از نوع
🔹
گاهی یک ستون نباید بدون مقدار باشد.
مثلاً:
اینجا:
پس این مورد معتبر است:
اما این مورد:
باعث
🔥 ترکیب
میتوانیم چند Constraint را همزمان استفاده کنیم:
در این جدول:
🔹 بررسی خطای Constraint
میتوانیم خطا را مدیریت کنیم:
چون
است، درج
⚠️
این نکته مهم است.
در SQLite:
است.
اما:
یک رشته خالی است.
بنابراین:
🔹 تعریف
روش رایج:
بعد میتوانیم رکورد اضافه کنیم:
در این حالت SQLite میتواند برای
🧠 خلاصه
مثلاً:
یعنی:
🎯 تمرین
جدول
سه جای خالی را با Constraint مناسب کامل کن.
پست ۲۰۰ از دوره جامع Python 🐍
محدودیتهای جدول در SQLite |
PRIMARY KEY و NOT NULLتا اینجا یاد گرفتیم چطور دادهها را در SQLite ذخیره، جستوجو، تغییر و حذف کنیم.
اما در یک Database واقعی فقط ذخیره کردن داده کافی نیست؛ باید مشخص کنیم چه دادهای مجاز است وارد جدول شود.
برای این کار از Constraintها استفاده میکنیم.
در این پست با دو Constraint مهم آشنا میشویم:
PRIMARY KEY
NOT NULL
🔹
PRIMARY KEYPRIMARY KEY مشخص میکند هر رکورد با چه مقداری بهصورت یکتا شناسایی شود.مثلاً:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT
)
"""
)
اینجا:
id → شناسه اصلی رکورد
هر رکورد باید شناسه منحصربهفرد داشته باشد.
مثلاً:
id | name
1 | Ali
2 | Sara
3 | Reza
🔹 جلوگیری از شناسه تکراری
اگر بخواهیم دوباره
id = 1 را وارد کنیم:cursor.execute(
"INSERT INTO users (id, name) VALUES (?, ?)",
(1, "Mina")
)
SQLite خطایی از نوع
IntegrityError ایجاد میکند، چون مقدار 1 قبلاً بهعنوان PRIMARY KEY استفاده شده است.🔹
NOT NULLگاهی یک ستون نباید بدون مقدار باشد.
مثلاً:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
"""
)
اینجا:
name → نباید NULL باشد
پس این مورد معتبر است:
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
اما این مورد:
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
(None,)
)
باعث
IntegrityError میشود.🔥 ترکیب
PRIMARY KEY و NOT NULLمیتوانیم چند Constraint را همزمان استفاده کنیم:
cursor.execute(
"""
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL
)
"""
)
در این جدول:
id → شناسه اصلی و یکتا
name → نباید NULL باشد
price → نباید NULL باشد
🔹 بررسی خطای Constraint
میتوانیم خطا را مدیریت کنیم:
import sqlite3
try:
cursor.execute(
"INSERT INTO products (name, price) VALUES (?, ?)",
(None, 1200)
)
connection.commit()
except sqlite3.IntegrityError as error:
print("Constraint error:", error)
چون
name دارای:NOT NULL
است، درج
None مجاز نیست.⚠️
NOT NULL با رشته خالی یکی نیستاین نکته مهم است.
name = None
در SQLite:
NULL
است.
اما:
name = ""
یک رشته خالی است.
بنابراین:
None → NULL
"" → empty string
NOT NULL جلوی NULL را میگیرد، اما الزاماً جلوی رشته خالی را نمیگیرد.🔹 تعریف
PRIMARY KEY در هنگام ساخت جدولروش رایج:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
بعد میتوانیم رکورد اضافه کنیم:
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
connection.commit()
در این حالت SQLite میتواند برای
INTEGER PRIMARY KEY مقدار id را بهصورت خودکار تعیین کند.🧠 خلاصه
PRIMARY KEY → شناسایی یکتای رکورد
NOT NULL → جلوگیری از مقدار NULL
مثلاً:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
یعنی:
id → شناسه اصلی
name → باید مقدار داشته باشد
🎯 تمرین
جدول
students را طوری کامل کن که:id کلید اصلی باشد.name نتواند NULL باشد.score هم نتواند NULL باشد.cursor.execute(
"""
CREATE TABLE students (
id ______,
name TEXT ______,
score INTEGER ______
)
"""
)
سه جای خالی را با Constraint مناسب کامل کن.
پست ۲۰۰ از دوره جامع Python 🐍
hack2.py
57.5 KB
💻🕶 شبیهساز هک با Python
این بار یک پروژه متفاوت ساختم؛ یک Hack Simulator با Python که فضای یک عملیات هکری را بهصورت شبیهسازیشده نمایش میدهد. 😎
در این پروژه اتفاقاتی مثل:
🔹 بررسی هدف
🔹 نمایش مراحل عملیات
🔹 شبیهسازی تستهای امنیتی
🔹 نمایش وضعیتها و نتایج
🔹 و افکتهای ترمینالی
بهصورت نمایشی و آموزشی اجرا میشوند.
⚠️ نکته مهم: این پروژه برای آموزش Python، آشنایی با مفاهیم امنیت و ساخت شبیهساز طراحی شده و بهخودیخود به معنی هک واقعی یا دسترسی غیرمجاز به سیستمها نیست.
🐍 هدف اصلی پروژه اینه که ببینیم چطور میتوانیم با Python یک پروژه جذاب و تعاملی بسازیم.
اگر دوست دارید، میتونم نسخههای پیشرفتهتر این شبیهساز رو هم توسعه بدم؛ مثلاً با GUI، لاگهای واقعیتر، مراحل تعاملی و سناریوهای مختلف امنیتی.
پست آموزشی دوره جامع Python 🐍
این بار یک پروژه متفاوت ساختم؛ یک Hack Simulator با Python که فضای یک عملیات هکری را بهصورت شبیهسازیشده نمایش میدهد. 😎
در این پروژه اتفاقاتی مثل:
🔹 بررسی هدف
🔹 نمایش مراحل عملیات
🔹 شبیهسازی تستهای امنیتی
🔹 نمایش وضعیتها و نتایج
🔹 و افکتهای ترمینالی
بهصورت نمایشی و آموزشی اجرا میشوند.
⚠️ نکته مهم: این پروژه برای آموزش Python، آشنایی با مفاهیم امنیت و ساخت شبیهساز طراحی شده و بهخودیخود به معنی هک واقعی یا دسترسی غیرمجاز به سیستمها نیست.
🐍 هدف اصلی پروژه اینه که ببینیم چطور میتوانیم با Python یک پروژه جذاب و تعاملی بسازیم.
اگر دوست دارید، میتونم نسخههای پیشرفتهتر این شبیهساز رو هم توسعه بدم؛ مثلاً با GUI، لاگهای واقعیتر، مراحل تعاملی و سناریوهای مختلف امنیتی.
پست آموزشی دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۱
جلوگیری از دادههای تکراری با
در پست قبل با
حالا میخواهیم با یک Constraint مهم دیگر آشنا شویم:
🔹 مثال ساده
فرض کنیم برای کاربران یک
حالا میتوانیم این کاربر را اضافه کنیم:
اما اگر دوباره بخواهیم:
SQLite خطای
🔹
هر دو میتوانند از تکراری شدن مقدار جلوگیری کنند، اما کاربردشان متفاوت است.
مثلاً:
اینجا:
🔹 مثال کاربردی
برای ایمیل کاربران نیز معمولاً نمیخواهیم یک ایمیل چند بار ثبت شود:
حالا دو کاربر نمیتوانند یک
🔹 مدیریت خطای
میتوانیم خطا را مدیریت کنیم:
این روش در برنامههای واقعی بسیار کاربردی است.
🔹
گاهی نمیخواهیم هر ستون بهتنهایی یکتا باشد؛ بلکه ترکیب چند ستون باید یکتا باشد.
مثلاً:
در این حالت یک دانشجو میتواند در چند دوره ثبتنام کند و یک دوره هم چند دانشجو داشته باشد.
اما ترکیب:
نباید دوبار تکرار شود.
⚠️ نکته مهم
مثلاً:
یعنی مقدارهای غیر
اما اگر بخواهیم مقدار حتماً وجود داشته باشد:
استفاده میکنیم.
یعنی:
🧠 خلاصه
مثلاً:
یعنی:
🎯 تمرین
جدول
سه جای خالی را با Constraint مناسب کامل کن.
پست ۲۰۱ از دوره جامع Python 🐍
جلوگیری از دادههای تکراری با
UNIQUE در SQLiteدر پست قبل با
PRIMARY KEY و NOT NULL آشنا شدیم.حالا میخواهیم با یک Constraint مهم دیگر آشنا شویم:
UNIQUE
UNIQUE مشخص میکند که مقدار یک ستون نباید در چند رکورد تکرار شود.🔹 مثال ساده
فرض کنیم برای کاربران یک
username داریم:cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT UNIQUE
)
"""
)
حالا میتوانیم این کاربر را اضافه کنیم:
cursor.execute(
"INSERT INTO users (username) VALUES (?)",
("ali",)
)
connection.commit()
اما اگر دوباره بخواهیم:
cursor.execute(
"INSERT INTO users (username) VALUES (?)",
("ali",)
)
connection.commit()
SQLite خطای
IntegrityError ایجاد میکند؛ چون username دارای UNIQUE است و مقدار ali قبلاً وجود دارد.🔹
UNIQUE چه تفاوتی با PRIMARY KEY دارد؟هر دو میتوانند از تکراری شدن مقدار جلوگیری کنند، اما کاربردشان متفاوت است.
PRIMARY KEY → شناسه اصلی رکورد
UNIQUE → جلوگیری از مقدار تکراری در یک ستون
مثلاً:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT UNIQUE
)
اینجا:
id → شناسه اصلی
username → باید یکتا باشد
🔹 مثال کاربردی
برای ایمیل کاربران نیز معمولاً نمیخواهیم یک ایمیل چند بار ثبت شود:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT UNIQUE,
email TEXT UNIQUE
)
"""
)
حالا دو کاربر نمیتوانند یک
username یا email یکسان داشته باشند.🔹 مدیریت خطای
UNIQUEمیتوانیم خطا را مدیریت کنیم:
import sqlite3
try:
cursor.execute(
"INSERT INTO users (username) VALUES (?)",
("ali",)
)
connection.commit()
except sqlite3.IntegrityError:
print("Username already exists")
این روش در برنامههای واقعی بسیار کاربردی است.
🔹
UNIQUE برای چند ستونگاهی نمیخواهیم هر ستون بهتنهایی یکتا باشد؛ بلکه ترکیب چند ستون باید یکتا باشد.
مثلاً:
cursor.execute(
"""
CREATE TABLE enrollments (
student_id INTEGER,
course_id INTEGER,
UNIQUE(student_id, course_id)
)
"""
)
در این حالت یک دانشجو میتواند در چند دوره ثبتنام کند و یک دوره هم چند دانشجو داشته باشد.
اما ترکیب:
student_id + course_id
نباید دوبار تکرار شود.
⚠️ نکته مهم
UNIQUE با NOT NULL یکی نیست.مثلاً:
username TEXT UNIQUE
یعنی مقدارهای غیر
NULL نباید تکراری باشند.اما اگر بخواهیم مقدار حتماً وجود داشته باشد:
username TEXT UNIQUE NOT NULL
استفاده میکنیم.
یعنی:
UNIQUE → تکراری نباشد
NOT NULL → خالی/NULL نباشد
🧠 خلاصه
PRIMARY KEY → شناسه اصلی و یکتا
NOT NULL → جلوگیری از NULL
UNIQUE → جلوگیری از مقدار تکراری
مثلاً:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT UNIQUE NOT NULL
)
یعنی:
id → شناسه اصلی
username → نه NULL باشد و نه تکراری
🎯 تمرین
جدول
users را طوری کامل کن که:id کلید اصلی باشد.username مقدار NULL نداشته باشد.username تکراری نباشد.cursor.execute(
"""
CREATE TABLE users (
id ______,
username TEXT ______ ______
)
"""
)
سه جای خالی را با Constraint مناسب کامل کن.
پست ۲۰۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۲
مقدار پیشفرض و اعتبارسنجی با
در پستهای قبل با Constraintهای:
آشنا شدیم.
حالا دو Constraint مهم دیگر را یاد میگیریم:
🔹
با
مثلاً:
اگر هنگام درج کاربر مقدار
SQLite بهصورت خودکار مقدار پیشفرض را قرار میدهد:
🔹 مقدار پیشفرض برای متن
مثلاً:
حالا:
مقدار
خواهد بود.
🔹
با
مثلاً فرض کنیم امتیاز دانشآموز باید بین
این مقدار معتبر است:
اما این مقدار:
باعث
پس شرط
🔹 چند Constraint در یک ستون
میتوانیم چند Constraint را ترکیب کنیم:
اینجا:
بنابراین:
نام محصول نباید
نام محصول نباید تکراری باشد.
قیمت نباید
قیمت نباید منفی باشد.
🔥 یک مثال کاربردی
فرض کنیم جدول حسابهای بانکی داریم:
حالا:
چون
خواهد بود.
اما این مقدار معتبر نیست:
چون:
برقرار نیست.
⚠️ نکته مهم
مثلاً:
یعنی اگر مقدار
اما:
یعنی مقدار
میتوانیم هر دو را با هم داشته باشیم:
🧠 خلاصه
مثلاً:
یعنی:
🎯 تمرین
جدول
اگر قیمت مشخص نشد،
قیمت منفی مجاز نباشد.
Constraintهای مناسب را در جای خالی قرار بده.
پست ۲۰۲ از دوره جامع Python 🐍
مقدار پیشفرض و اعتبارسنجی با
DEFAULT و CHECKدر پستهای قبل با Constraintهای:
PRIMARY KEY
NOT NULL
UNIQUE
آشنا شدیم.
حالا دو Constraint مهم دیگر را یاد میگیریم:
DEFAULT
CHECK
🔹
DEFAULTبا
DEFAULT میتوانیم برای یک ستون مقدار پیشفرض تعیین کنیم.مثلاً:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
active INTEGER DEFAULT 1
)
"""
)
اگر هنگام درج کاربر مقدار
active را مشخص نکنیم:cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
SQLite بهصورت خودکار مقدار پیشفرض را قرار میدهد:
active → 1
🔹 مقدار پیشفرض برای متن
DEFAULT فقط برای اعداد نیست.مثلاً:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
role TEXT DEFAULT 'user'
)
"""
)
حالا:
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
مقدار
role بهصورت خودکار:user
خواهد بود.
🔹
CHECKبا
CHECK میتوانیم مشخص کنیم یک مقدار باید یک شرط مشخص را رعایت کند.مثلاً فرض کنیم امتیاز دانشآموز باید بین
0 و 20 باشد:cursor.execute(
"""
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
score INTEGER CHECK(score >= 0 AND score <= 20)
)
"""
)
این مقدار معتبر است:
cursor.execute(
"INSERT INTO students (name, score) VALUES (?, ?)",
("Ali", 18)
)
اما این مقدار:
cursor.execute(
"INSERT INTO students (name, score) VALUES (?, ?)",
("Sara", 25)
)
باعث
IntegrityError میشود؛ چون:25 >= 0 → True
25 <= 20 → False
پس شرط
CHECK برقرار نیست.🔹 چند Constraint در یک ستون
میتوانیم چند Constraint را ترکیب کنیم:
cursor.execute(
"""
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
price REAL NOT NULL CHECK(price >= 0)
)
"""
)
اینجا:
id → PRIMARY KEY
name → NOT NULL + UNIQUE
price → NOT NULL + CHECK
بنابراین:
نام محصول نباید
NULL باشد.نام محصول نباید تکراری باشد.
قیمت نباید
NULL باشد.قیمت نباید منفی باشد.
🔥 یک مثال کاربردی
فرض کنیم جدول حسابهای بانکی داریم:
cursor.execute(
"""
CREATE TABLE accounts (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
balance REAL DEFAULT 0 CHECK(balance >= 0)
)
"""
)
حالا:
cursor.execute(
"INSERT INTO accounts (username) VALUES (?)",
("ali",)
)
چون
balance مشخص نشده، مقدار آن:0
خواهد بود.
اما این مقدار معتبر نیست:
cursor.execute(
"INSERT INTO accounts (username, balance) VALUES (?, ?)",
("sara", -100)
)
چون:
balance >= 0
برقرار نیست.
⚠️ نکته مهم
DEFAULT با NOT NULL متفاوت است.مثلاً:
age INTEGER DEFAULT 18
یعنی اگر مقدار
age ارسال نشود، مقدار 18 استفاده شود.اما:
age INTEGER NOT NULL
یعنی مقدار
NULL برای age مجاز نیست.میتوانیم هر دو را با هم داشته باشیم:
age INTEGER NOT NULL DEFAULT 18
🧠 خلاصه
PRIMARY KEY → شناسه اصلی و یکتا
NOT NULL → جلوگیری از NULL
UNIQUE → جلوگیری از مقدار تکراری
DEFAULT → مقدار پیشفرض
CHECK → بررسی یک شرط روی مقدار
مثلاً:
price REAL NOT NULL DEFAULT 0 CHECK(price >= 0)
یعنی:
price
↓
نباید NULL باشد
↓
اگر مقدار نداشت → 0
↓
نباید منفی باشد
🎯 تمرین
جدول
products را طوری کامل کن که:id کلید اصلی باشد.name اجباری و یکتا باشد.price اجباری باشد.اگر قیمت مشخص نشد،
0 قرار بگیرد.قیمت منفی مجاز نباشد.
cursor.execute(
"""
CREATE TABLE products (
id ______,
name TEXT ______ ______,
price REAL ______ ______ ______
)
"""
)
Constraintهای مناسب را در جای خالی قرار بده.
پست ۲۰۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۳
ارتباط بین جدولها با
تا اینجا Constraintهای مختلفی را یاد گرفتیم:
حالا میرسیم به یکی از مهمترین بخشهای Database:
🔹 یک مثال ساده
فرض کنیم دو جدول داریم:
هر سفارش متعلق به یک کاربر است.
جدول کاربران:
جدول سفارشها:
اینجا:
یعنی
🔹 درج داده معتبر
ابتدا یک کاربر ایجاد میکنیم:
فرض کنیم
حالا میتوانیم سفارش او را ثبت کنیم:
این ارتباط معتبر است:
⚠️ چرا Foreign Key مهم است؟
فرض کنیم کاربری با
اگر بخواهیم:
در یک Database با Foreign Key فعال، این عملیات مجاز نیست؛ چون کاربر
این کار از ایجاد رکوردهای بدون مرجع معتبر جلوگیری میکند.
🔹 فعال کردن Foreign Key در SQLite
یک نکته بسیار مهم درباره SQLite وجود دارد.
برای فعال بودن بررسی Foreign Key باید آن را برای Connection فعال کنیم:
بعد از آن میتوانیم جدولها را ایجاد کنیم.
🔹 مثال کامل
در این مثال:
🔹 Foreign Key و
بعداً میتوانیم اطلاعات دو جدول را با
مثلاً:
خروجی:
یعنی سفارش را به کاربر مربوط به آن متصل کردهایم.
🧠 خلاصه
مثلاً:
یعنی:
و در SQLite بهتر است صریحاً فعال کنیم:
🎯 تمرین
دو جدول زیر را کامل کن:
طوری
را مرجع قرار دهد.
پست ۲۰۳ از دوره جامع Python 🐍
ارتباط بین جدولها با
FOREIGN KEYتا اینجا Constraintهای مختلفی را یاد گرفتیم:
PRIMARY KEY
NOT NULL
UNIQUE
DEFAULT
CHECK
حالا میرسیم به یکی از مهمترین بخشهای Database:
FOREIGN KEY
FOREIGN KEY برای ایجاد ارتباط بین جدولها استفاده میشود.🔹 یک مثال ساده
فرض کنیم دو جدول داریم:
users
orders
هر سفارش متعلق به یک کاربر است.
جدول کاربران:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
"""
)
جدول سفارشها:
cursor.execute(
"""
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id)
)
"""
)
اینجا:
users.id
↑
│
orders.user_id
یعنی
user_id در جدول orders به id در جدول users اشاره میکند.🔹 درج داده معتبر
ابتدا یک کاربر ایجاد میکنیم:
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
فرض کنیم
id کاربر 1 شده است.حالا میتوانیم سفارش او را ثبت کنیم:
cursor.execute(
"INSERT INTO orders (user_id) VALUES (?)",
(1,)
)
این ارتباط معتبر است:
User 1
↓
Order 1
⚠️ چرا Foreign Key مهم است؟
فرض کنیم کاربری با
id = 999 وجود ندارد.اگر بخواهیم:
cursor.execute(
"INSERT INTO orders (user_id) VALUES (?)",
(999,)
)
در یک Database با Foreign Key فعال، این عملیات مجاز نیست؛ چون کاربر
999 وجود ندارد.این کار از ایجاد رکوردهای بدون مرجع معتبر جلوگیری میکند.
🔹 فعال کردن Foreign Key در SQLite
یک نکته بسیار مهم درباره SQLite وجود دارد.
برای فعال بودن بررسی Foreign Key باید آن را برای Connection فعال کنیم:
import sqlite3
connection = sqlite3.connect("app.db")
connection.execute("PRAGMA foreign_keys = ON")
بعد از آن میتوانیم جدولها را ایجاد کنیم.
🔹 مثال کامل
import sqlite3
connection = sqlite3.connect("app.db")
connection.execute("PRAGMA foreign_keys = ON")
cursor = connection.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
"""
)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
)
"""
)
cursor.execute(
"INSERT INTO users (name) VALUES (?)",
("Ali",)
)
user_id = cursor.lastrowid
cursor.execute(
"INSERT INTO orders (user_id) VALUES (?)",
(user_id,)
)
connection.commit()
در این مثال:
users
↓
id = 1
orders
↓
user_id = 1
🔹 Foreign Key و
JOINبعداً میتوانیم اطلاعات دو جدول را با
JOIN کنار هم قرار دهیم.مثلاً:
cursor.execute(
"""
SELECT users.name, orders.id
FROM orders
JOIN users ON orders.user_id = users.id
"""
)
rows = cursor.fetchall()
for row in rows:
print(row)
خروجی:
('Ali', 1)یعنی سفارش را به کاربر مربوط به آن متصل کردهایم.
🧠 خلاصه
PRIMARY KEY
↓
شناسه اصلی جدول
FOREIGN KEY
↓
اشاره به رکورد جدول دیگر
مثلاً:
FOREIGN KEY (user_id)
REFERENCES users(id)
یعنی:
مقدار
user_idباید به یک
idمعتبر در جدول
usersاشاره کند.
و در SQLite بهتر است صریحاً فعال کنیم:
connection.execute("PRAGMA foreign_keys = ON")🎯 تمرین
دو جدول زیر را کامل کن:
import sqlite3
connection = sqlite3.connect("school.db")
connection.execute("PRAGMA foreign_keys = ON")
cursor = connection.cursor()
cursor.execute(
"""
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
"""
)
cursor.execute(
"""
CREATE TABLE courses (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
student_id INTEGER,
______________________________
)
"""
)
طوری
FOREIGN KEY را تعریف کن که:courses.student_id
↓
students.id
را مرجع قرار دهد.
پست ۲۰۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۴
رفتار
در پست قبل با
حالا میخواهیم ببینیم اگر رکورد اصلی حذف یا تغییر کند، رکورد وابسته چه اتفاقی میافتد.
برای این کار از:
استفاده میکنیم.
🔹
اگر کاربر حذف شود، رکوردهای وابسته او نیز حذف میشوند:
مثلاً:
🔹
اگر نمیخواهیم سفارش حذف شود، میتوانیم ارتباط آن را
پس:
⚠️ در این حالت
🔹
میتوانیم حذف کاربر را تا زمانی که رکورد وابسته وجود دارد، ممنوع کنیم:
اگر کاربر سفارش داشته باشد:
🔹
اگر مقدار کلید اصلی والد تغییر کند، مقدار Foreign Key وابسته نیز تغییر میکند:
مثلاً:
⚠️ نکته مهم در SQLite
برای فعال بودن Foreign Key باید آن را روی Connection فعال کنیم:
🧠 خلاصه
🎯 تمرین
کد زیر را کامل کن تا با حذف کاربر، سفارشهای او هم حذف شوند:
همچنین:
را فراموش نکن.
پست ۲۰۴ از دوره جامع Python 🐍
رفتار
FOREIGN KEY هنگام حذف و تغییر رکورددر پست قبل با
FOREIGN KEY آشنا شدیم.حالا میخواهیم ببینیم اگر رکورد اصلی حذف یا تغییر کند، رکورد وابسته چه اتفاقی میافتد.
برای این کار از:
ON DELETE
ON UPDATE
استفاده میکنیم.
🔹
ON DELETE CASCADEاگر کاربر حذف شود، رکوردهای وابسته او نیز حذف میشوند:
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
)
مثلاً:
User 1
├── Order 10
└── Order 11
Delete User 1
↓
Order 10 ❌
Order 11 ❌
🔹
ON DELETE SET NULLاگر نمیخواهیم سفارش حذف شود، میتوانیم ارتباط آن را
NULL کنیم:FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE SET NULL
پس:
User 1 حذف میشود
↓
Order باقی میماند
↓
user_id = NULL
⚠️ در این حالت
user_id نباید NOT NULL باشد.🔹
ON DELETE RESTRICTمیتوانیم حذف کاربر را تا زمانی که رکورد وابسته وجود دارد، ممنوع کنیم:
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE RESTRICT
اگر کاربر سفارش داشته باشد:
Delete User
↓
❌ حذف مجاز نیست
🔹
ON UPDATE CASCADEاگر مقدار کلید اصلی والد تغییر کند، مقدار Foreign Key وابسته نیز تغییر میکند:
FOREIGN KEY (user_id)
REFERENCES users(id)
ON UPDATE CASCADE
مثلاً:
users.id = 100
orders.user_id = 100
100 → 200
users.id = 200
orders.user_id = 200
⚠️ نکته مهم در SQLite
برای فعال بودن Foreign Key باید آن را روی Connection فعال کنیم:
connection.execute("PRAGMA foreign_keys = ON")🧠 خلاصه
ON DELETE CASCADE
→ حذف رکوردهای وابسته
ON DELETE SET NULL
→ حفظ رکورد وابسته و قرار دادن Foreign Key روی NULL
ON DELETE RESTRICT
→ جلوگیری از حذف رکورد والد
ON UPDATE CASCADE
→ بهروزرسانی Foreign Key هنگام تغییر کلید والد
🎯 تمرین
کد زیر را کامل کن تا با حذف کاربر، سفارشهای او هم حذف شوند:
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
______________________________
)
همچنین:
connection.execute("PRAGMA foreign_keys = ON")را فراموش نکن.
پست ۲۰۴ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۵
بررسی ساختار جدول با
تا اینجا یاد گرفتیم چطور جدول بسازیم و Constraintهایی مثل:
را تعریف کنیم.
اما گاهی لازم است ساختار یک جدول موجود را بررسی کنیم.
مثلاً بخواهیم بدانیم:
چه ستونهایی دارد؟
نوع هر ستون چیست؟
کدام ستون
کدام ستون
مقدار پیشفرض هر ستون چیست؟
در SQLite میتوانیم از:
استفاده کنیم.
🔹 بررسی ساختار جدول
فرض کنیم جدول زیر را داریم:
حالا:
خروجی شامل اطلاعات مربوط به ستونهای جدول خواهد بود.
مثلاً:
🔹 معنی اطلاعات خروجی
هر ردیف اطلاعات یک ستون را نشان میدهد.
ساختار خروجی
یعنی:
مثلاً:
یعنی:
پس
🔹 بررسی یک جدول با Python
میتوانیم اطلاعات را خواناتر نمایش دهیم:
خروجی تقریباً:
🔹 چرا
فرض کنید برنامهای داریم که Database آن قبلاً ساخته شده است.
بهجای اینکه حدس بزنیم جدول چه ساختاری دارد، میتوانیم آن را از خود SQLite بررسی کنیم.
مثلاً:
حالا:
⚠️ نکته مهم درباره نام جدول
در مثال بالا
برای مقادیر باید از Placeholder استفاده کنیم:
اما نام جدول و ستون در SQLite به شکل معمول با
بنابراین اگر نام جدول از ورودی کاربر میآید، نباید آن را بدون اعتبارسنجی مستقیماً وارد SQL کنیم.
🔹 مثال کاربردی
میتوانیم بررسی کنیم آیا یک ستون وجود دارد یا نه:
خروجی:
این روش در ابزارهای مدیریت Database و Migrationها میتواند مفید باشد.
🧠 خلاصه
ساختار هر ستون:
🎯 تمرین
جدول زیر را در نظر بگیر:
با
پست ۲۰۵ از دوره جامع Python 🐍
بررسی ساختار جدول با
PRAGMA table_info()تا اینجا یاد گرفتیم چطور جدول بسازیم و Constraintهایی مثل:
PRIMARY KEY
NOT NULL
UNIQUE
DEFAULT
CHECK
FOREIGN KEY
را تعریف کنیم.
اما گاهی لازم است ساختار یک جدول موجود را بررسی کنیم.
مثلاً بخواهیم بدانیم:
چه ستونهایی دارد؟
نوع هر ستون چیست؟
کدام ستون
PRIMARY KEY است؟کدام ستون
NOT NULL است؟مقدار پیشفرض هر ستون چیست؟
در SQLite میتوانیم از:
PRAGMA table_info()
استفاده کنیم.
🔹 بررسی ساختار جدول
فرض کنیم جدول زیر را داریم:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
age INTEGER DEFAULT 18
)
"""
)
حالا:
cursor.execute("PRAGMA table_info(users)")
columns = cursor.fetchall()
for column in columns:
print(column)خروجی شامل اطلاعات مربوط به ستونهای جدول خواهد بود.
مثلاً:
(0, 'id', 'INTEGER', 0, None, 1)
(1, 'username', 'TEXT', 1, None, 0)
(2, 'age', 'INTEGER', 0, '18', 0)
🔹 معنی اطلاعات خروجی
هر ردیف اطلاعات یک ستون را نشان میدهد.
ساختار خروجی
table_info به شکل کلی:(cid, name, type, notnull, dflt_value, pk)
یعنی:
cid → شماره ستون
name → نام ستون
type → نوع داده
notnull → آیا NOT NULL است؟
dflt_value → مقدار پیشفرض
pk → آیا PRIMARY KEY است؟
مثلاً:
(1, 'username', 'TEXT', 1, None, 0)
یعنی:
name → username
type → TEXT
notnull → 1
pk → 0
پس
username دارای NOT NULL است و Primary Key نیست.🔹 بررسی یک جدول با Python
میتوانیم اطلاعات را خواناتر نمایش دهیم:
cursor.execute("PRAGMA table_info(users)")
for column in cursor.fetchall():
cid, name, data_type, not_null, default_value, primary_key = column
print(
f"Name: {name}, "
f"Type: {data_type}, "
f"NOT NULL: {bool(not_null)}, "
f"Default: {default_value}, "
f"Primary Key: {bool(primary_key)}"
)خروجی تقریباً:
Name: id, Type: INTEGER, NOT NULL: False, Default: None, Primary Key: True
Name: username, Type: TEXT, NOT NULL: True, Default: None, Primary Key: False
Name: age, Type: INTEGER, NOT NULL: False, Default: 18, Primary Key: False
🔹 چرا
PRAGMA مهم است؟فرض کنید برنامهای داریم که Database آن قبلاً ساخته شده است.
بهجای اینکه حدس بزنیم جدول چه ساختاری دارد، میتوانیم آن را از خود SQLite بررسی کنیم.
مثلاً:
def show_table_structure(cursor, table_name):
cursor.execute(f"PRAGMA table_info({table_name})")
for column in cursor.fetchall():
print(column)
حالا:
show_table_structure(cursor, "users")
⚠️ نکته مهم درباره نام جدول
در مثال بالا
table_name مستقیماً داخل SQL قرار گرفته است:f"PRAGMA table_info({table_name})"برای مقادیر باید از Placeholder استفاده کنیم:
WHERE name = ?
اما نام جدول و ستون در SQLite به شکل معمول با
? بهعنوان parameter قابل جایگزینی نیست.بنابراین اگر نام جدول از ورودی کاربر میآید، نباید آن را بدون اعتبارسنجی مستقیماً وارد SQL کنیم.
🔹 مثال کاربردی
میتوانیم بررسی کنیم آیا یک ستون وجود دارد یا نه:
cursor.execute("PRAGMA table_info(users)")
columns = cursor.fetchall()
column_names = [column[1] for column in columns]
if "username" in column_names:
print("username exists")خروجی:
username exists
این روش در ابزارهای مدیریت Database و Migrationها میتواند مفید باشد.
🧠 خلاصه
PRAGMA table_info(table_name)
↓
بررسی ساختار جدول
↓
نام ستون
نوع داده
NOT NULL
DEFAULT
PRIMARY KEY
ساختار هر ستون:
cid
name
type
notnull
dflt_value
pk
🎯 تمرین
جدول زیر را در نظر بگیر:
cursor.execute(
"""
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
price REAL NOT NULL DEFAULT 0
)
"""
)
با
PRAGMA table_info(products) برنامهای بنویس که برای هر ستون این اطلاعات را چاپ کند:نام ستون
نوع داده
NOT NULL
PRIMARY KEY
DEFAULT
پست ۲۰۵ از دوره جامع Python 🐍
❌ پایان پروژه CodeBox
دوستان، پروژه CodeBox | Telegram Coding Lab بهطور کامل متوقف و از دسترس خارج خواهد شد.
بعد از بررسی معماری و ریسکهای امنیتی پروژه، تصمیم گرفتم ادامه این پروژه در شکل فعلی منطقی نیست. بهخصوص برای پروژهای که هدف آن فراهم کردن محیط کدنویسی و در آینده اجرای کد کاربران بود، امنیت و ایزولهسازی مناسب اهمیت بسیار زیادی دارد.
به همین دلیل ترجیح دادم بهجای ادامه دادن با یک معماری که از نظر امنیتی به اندازه کافی مطمئن نیست، پروژه را بهطور کامل کنار بگذارم.
🔐 امنیت کاربران و اطلاعات همیشه اولویت دارد.
از تمام دوستانی که در مدت کوتاه فعالیت CodeBox از ربات استفاده کردند یا پروژه را دنبال کردند، ممنونم.
این پروژه به پایان رسید؛ اما تجربهای که از ساخت و طراحی آن به دست آمد، در پروژههای آینده استفاده خواهد شد.
CodeBox — Project Closed.
دوستان، پروژه CodeBox | Telegram Coding Lab بهطور کامل متوقف و از دسترس خارج خواهد شد.
بعد از بررسی معماری و ریسکهای امنیتی پروژه، تصمیم گرفتم ادامه این پروژه در شکل فعلی منطقی نیست. بهخصوص برای پروژهای که هدف آن فراهم کردن محیط کدنویسی و در آینده اجرای کد کاربران بود، امنیت و ایزولهسازی مناسب اهمیت بسیار زیادی دارد.
به همین دلیل ترجیح دادم بهجای ادامه دادن با یک معماری که از نظر امنیتی به اندازه کافی مطمئن نیست، پروژه را بهطور کامل کنار بگذارم.
🔐 امنیت کاربران و اطلاعات همیشه اولویت دارد.
از تمام دوستانی که در مدت کوتاه فعالیت CodeBox از ربات استفاده کردند یا پروژه را دنبال کردند، ممنونم.
این پروژه به پایان رسید؛ اما تجربهای که از ساخت و طراحی آن به دست آمد، در پروژههای آینده استفاده خواهد شد.
CodeBox — Project Closed.
🐍 آموزش جامع Python — پست ۲۰۶
آشنایی با Index در SQLite |
وقتی تعداد رکوردهای یک جدول زیاد میشود، جستوجو ممکن است کندتر شود.
SQLite برای سریعتر کردن بعضی جستوجوها از Index استفاده میکند.
🔹 ساخت Index
فرض کنیم جدول کاربران را داریم:
اگر زیاد بر اساس
ساختار کلی:
🔹 جستوجو با Index
حالا میتوانیم مثل قبل جستوجو کنیم:
نیازی نیست در دستور
🔹 Index برای چند ستون
گاهی جستوجو بر اساس چند ستون انجام میشود:
این Index برای جستوجوهایی که با
اما لزوماً برای جستوجویی که فقط بر اساس
🔹 جلوگیری از Index تکراری
برای اینکه اگر Index از قبل وجود داشت خطا نگیریم:
⚠️ نکته مهم
Index همیشه مفید نیست:
جستوجو و فیلتر بعضی ستونها را سریعتر میکند.
فضای ذخیرهسازی بیشتری مصرف میکند.
درج، حذف و تغییر دادهها را ممکن است کمی کندتر کند.
همچنین اگر ستونی از قبل
🧠 خلاصه
🎯 تمرین
برای جدول
پست ۲۰۶ از دوره جامع Python 🐍
آشنایی با Index در SQLite |
CREATE INDEXوقتی تعداد رکوردهای یک جدول زیاد میشود، جستوجو ممکن است کندتر شود.
SQLite برای سریعتر کردن بعضی جستوجوها از Index استفاده میکند.
🔹 ساخت Index
فرض کنیم جدول کاربران را داریم:
cursor.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
age INTEGER
)
"""
)
اگر زیاد بر اساس
username جستوجو کنیم، میتوانیم برای آن Index بسازیم:cursor.execute(
"CREATE INDEX idx_users_username ON users(username)"
)
ساختار کلی:
CREATE INDEX index_name
ON table_name(column_name);
🔹 جستوجو با Index
حالا میتوانیم مثل قبل جستوجو کنیم:
cursor.execute(
"SELECT * FROM users WHERE username = ?",
("ali",)
)
users = cursor.fetchall()
نیازی نیست در دستور
SELECT نام Index را مشخص کنیم؛ SQLite میتواند در صورت مناسب بودن از آن استفاده کند.🔹 Index برای چند ستون
گاهی جستوجو بر اساس چند ستون انجام میشود:
cursor.execute(
"""
CREATE INDEX idx_users_name_age
ON users(username, age)
"""
)
این Index برای جستوجوهایی که با
username شروع میشوند، میتواند مفید باشد؛ مثلاً:SELECT * FROM users
WHERE username = ? AND age = ?;
اما لزوماً برای جستوجویی که فقط بر اساس
age است، به همان اندازه مفید نیست.🔹 جلوگیری از Index تکراری
برای اینکه اگر Index از قبل وجود داشت خطا نگیریم:
cursor.execute(
"""
CREATE INDEX IF NOT EXISTS idx_users_username
ON users(username)
"""
)
⚠️ نکته مهم
Index همیشه مفید نیست:
جستوجو و فیلتر بعضی ستونها را سریعتر میکند.
فضای ذخیرهسازی بیشتری مصرف میکند.
درج، حذف و تغییر دادهها را ممکن است کمی کندتر کند.
همچنین اگر ستونی از قبل
PRIMARY KEY یا UNIQUE باشد، SQLite معمولاً برای اعمال این محدودیتها Index مربوط را ایجاد میکند؛ بنابراین Index مشابه و غیرضروری نساز.🧠 خلاصه
CREATE INDEX → ایجاد Index
IF NOT EXISTS → جلوگیری از خطا در صورت وجود Index
🎯 تمرین
برای جدول
products یک Index با نام idx_products_name روی ستون name بساز.cursor.execute(
"""
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL
)
"""
)
# کد ساخت Index را اینجا بنویس
پست ۲۰۶ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۷
حذف و بررسی Index در SQLite
در پست قبل یاد گرفتیم با
حالا میخواهیم یاد بگیریم چطور Indexها را بررسی و حذف کنیم و بفهمیم SQLite از چه Indexهایی استفاده میکند.
🔹 حذف Index با
اگر دیگر به یک Index نیاز نداشته باشیم، میتوانیم آن را حذف کنیم:
برای جلوگیری از خطا در صورت نبودن Index:
⚠️ حذف Index، ستون یا رکوردهای جدول را حذف نمیکند؛ فقط خود Index حذف میشود.
🔹 مشاهده Indexهای یک جدول
برای بررسی Indexهای جدول
این دستور اطلاعات Indexهای جدول را نمایش میدهد؛ از جمله نام Index و اینکه آیا یکتا است یا نه.
🔹 بررسی ستونهای یک Index
با
برای مثال، اگر Index روی
🔹 بررسی استفاده از Index با
میتوانیم از SQLite بپرسیم برای اجرای یک Query چه برنامهای انتخاب کرده است:
در خروجی ممکن است عبارتی مانند
اینها بهتنهایی معیار قطعی سرعت نیستند؛ برای ارزیابی عملکرد باید Query و دادههای واقعی را هم در نظر بگیریم.
🧠 خلاصه
🎯 تمرین
فرض کن Index زیر را ساختهای:
حالا کدی بنویس که:
Indexهای جدول
مشخص کند Index
در پایان، همان Index را با
پست ۲۰۷ از دوره جامع Python 🐍
حذف و بررسی Index در SQLite
در پست قبل یاد گرفتیم با
CREATE INDEX جستوجو در بعضی ستونها را سریعتر کنیم.حالا میخواهیم یاد بگیریم چطور Indexها را بررسی و حذف کنیم و بفهمیم SQLite از چه Indexهایی استفاده میکند.
🔹 حذف Index با
DROP INDEXاگر دیگر به یک Index نیاز نداشته باشیم، میتوانیم آن را حذف کنیم:
cursor.execute(
"DROP INDEX idx_users_username"
)
برای جلوگیری از خطا در صورت نبودن Index:
cursor.execute(
"DROP INDEX IF EXISTS idx_users_username"
)
⚠️ حذف Index، ستون یا رکوردهای جدول را حذف نمیکند؛ فقط خود Index حذف میشود.
🔹 مشاهده Indexهای یک جدول
برای بررسی Indexهای جدول
users از PRAGMA index_list() استفاده میکنیم:cursor.execute("PRAGMA index_list(users)")
for index in cursor.fetchall():
print(index)این دستور اطلاعات Indexهای جدول را نمایش میدهد؛ از جمله نام Index و اینکه آیا یکتا است یا نه.
🔹 بررسی ستونهای یک Index
با
PRAGMA index_info() میتوانیم ببینیم یک Index روی کدام ستونها ساخته شده است:cursor.execute(
"PRAGMA index_info(idx_users_username)"
)
for column in cursor.fetchall():
print(column)
برای مثال، اگر Index روی
username باشد، اطلاعات همان ستون نمایش داده میشود.🔹 بررسی استفاده از Index با
EXPLAIN QUERY PLANمیتوانیم از SQLite بپرسیم برای اجرای یک Query چه برنامهای انتخاب کرده است:
cursor.execute(
"""
EXPLAIN QUERY PLAN
SELECT * FROM users
WHERE username = ?
""",
("ali",)
)
for row in cursor.fetchall():
print(row)
در خروجی ممکن است عبارتی مانند
SEARCH یا SCAN ببینیم.SEARCH معمولاً یعنی SQLite از یک روش جستوجوی هدفمند استفاده میکند.SCAN یعنی SQLite رکوردها یا بخش بزرگی از آنها را پیمایش میکند.اینها بهتنهایی معیار قطعی سرعت نیستند؛ برای ارزیابی عملکرد باید Query و دادههای واقعی را هم در نظر بگیریم.
🧠 خلاصه
DROP INDEX → حذف Index
PRAGMA index_list() → فهرست Indexهای جدول
PRAGMA index_info() → بررسی ستونهای Index
EXPLAIN QUERY PLAN → مشاهده برنامه اجرای Query
🎯 تمرین
فرض کن Index زیر را ساختهای:
cursor.execute(
"""
CREATE INDEX IF NOT EXISTS idx_products_name
ON products(name)
"""
)
حالا کدی بنویس که:
Indexهای جدول
products را نمایش دهد.مشخص کند Index
idx_products_name روی کدام ستون ساخته شده است.در پایان، همان Index را با
DROP INDEX IF EXISTS حذف کند.پست ۲۰۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۲۰۸
دریافت رکوردها به شکل دیکشنری با
تا اینجا با
مثلاً:
اینجا برای دسترسی به
اما راه خواناتری هم وجود دارد:
🔹 فعال کردن
کافی است
حالا میتوانیم رکوردها را با نام ستون بخوانیم:
دیگر لازم نیست به خاطر بسپاریم
🔹 دریافت همه رکوردها
این روش برای نمایش اطلاعات کاربران، محصولات و سفارشها خواناتر است.
🔹 دسترسی با شماره ستون هم ممکن است
هر دو روش قابل استفادهاند.
⚠️ نکته مهم
نامی که داخل براکت قرار میدهیم باید با نام یکی از ستونهای نتیجه Query مطابقت داشته باشد.
مثلاً:
در این نتیجه میتوانیم بنویسیم:
اما اگر ستون
🧠 خلاصه
بعد از آن:
بهجای وابستگی به شماره ستونها، از نام آنها استفاده میکنیم.
🎯 تمرین
جدول
اتصال را طوری تنظیم کن که نتیجه Query به شکل
پست ۲۰۸ از دوره جامع Python 🐍
دریافت رکوردها به شکل دیکشنری با
sqlite3.Rowتا اینجا با
fetchone() و fetchall() آشنا شدیم. بهصورت پیشفرض، نتیجه Queryها معمولاً به شکل Tuple برمیگردد.مثلاً:
cursor.execute(
"SELECT id, username, age FROM users"
)
user = cursor.fetchone()
print(user[1])
اینجا برای دسترسی به
username باید شماره ستون را بدانیم.اما راه خواناتری هم وجود دارد:
sqlite3.Row.🔹 فعال کردن
sqlite3.Rowکافی است
row_factory اتصال را تنظیم کنیم:import sqlite3
connection = sqlite3.connect("app.db")
connection.row_factory = sqlite3.Row
cursor = connection.cursor()
حالا میتوانیم رکوردها را با نام ستون بخوانیم:
cursor.execute(
"SELECT id, username, age FROM users"
)
user = cursor.fetchone()
if user is not None:
print(user["username"])
print(user["age"])
دیگر لازم نیست به خاطر بسپاریم
username در کدام موقعیت قرار دارد.🔹 دریافت همه رکوردها
cursor.execute(
"SELECT id, username, age FROM users"
)
users = cursor.fetchall()
for user in users:
print(user["id"], user["username"])
این روش برای نمایش اطلاعات کاربران، محصولات و سفارشها خواناتر است.
🔹 دسترسی با شماره ستون هم ممکن است
sqlite3.Row همچنان امکان دسترسی با Index را فراهم میکند:print(user[0])
print(user["username"])
هر دو روش قابل استفادهاند.
⚠️ نکته مهم
نامی که داخل براکت قرار میدهیم باید با نام یکی از ستونهای نتیجه Query مطابقت داشته باشد.
مثلاً:
SELECT username FROM users
در این نتیجه میتوانیم بنویسیم:
user["username"]
اما اگر ستون
age را انتخاب نکرده باشیم، نمیتوانیم آن را از این ردیف دریافت کنیم.🧠 خلاصه
connection.row_factory = sqlite3.Row
بعد از آن:
user["username"]
user["age"]
بهجای وابستگی به شماره ستونها، از نام آنها استفاده میکنیم.
🎯 تمرین
جدول
products را در نظر بگیر:id | name | price
اتصال را طوری تنظیم کن که نتیجه Query به شکل
sqlite3.Row باشد. سپس تمام محصولات را بخوان و برای هر محصول، نام و قیمت را با استفاده از نام ستونها چاپ کن.پست ۲۰۸ از دوره جامع Python 🐍