עדכון ומחיקה: UPDATE ו-DELETE לפי id — מ-SQL ומ-Python
- לכתוב UPDATE שמעדכן עמודה אחת או כמה עמודות לפי id
- להסביר למה UPDATE בלי WHERE מסוכן, ומה הוא עושה
- לבצע עדכון מ-Python עם פרמטרים ו-commit
- להשתמש ב-rowcount כדי לגלות שלא עודכנה אף שורה (הרשומה לא קיימת)
- לכתוב DELETE שמוחק רשומה אחת לפי id
- להסביר למה DELETE בלי WHERE הוא הפקודה המסוכנת ביותר ב-SQL
- למחוק מ-Python עם פרמטרים ו-commit, ולזהות “לא נמצא” עם rowcount
- להבין ש-AUTO_INCREMENT לא ממחזר id של רשומה שנמחקה
מה בשיעור
השיעור הזה בנוי משני פרקים, באותו סדר כמו במצגת:
- פרק ראשון — UPDATE לפי id: עדכון רשומה מ-SQL ומ-Python
- פרק שני — DELETE לפי id: מחיקת רשומה מ-SQL ומ-Python
פרק ראשון: UPDATE לפי id — עדכון רשומה מ-SQL ומ-Python
מה נלמד?
UPDATE = ה-U של CRUD: שינוי של רשומה קיימת.
- התחביר
UPDATE ... SET ... WHERE .... - עדכון של עמודה אחת, ושל כמה עמודות.
- למה
WHEREהוא חובה. - עדכון מ-Python, ו-
rowcount.
למה צריך את זה?
כל מערכת צריכה לעדכן: סטודנט שינה אימייל, מחיר מוצר השתנה, הזמנה עברה ל"נשלחה". ב-API של נושא Students API – שרת עם מסד נתונים, PUT /students/7 = UPDATE students SET ... WHERE id = 7. ו-UPDATE הוא גם הפקודה שהכי קל להרוס איתה נתונים, אם שוכחים פרט אחד.
הסבר מהבסיס
התחביר
UPDATE students
SET age = 25
WHERE id = 1;UPDATE students— איזו טבלה.SET age = 25— איזו עמודה מקבלת איזה ערך חדש. (כאן=הוא השמה, ובתוךWHEREהוא השוואה. אותו סימן, שני תפקידים.)WHERE id = 1— איזו שורה (או אילו שורות) מעדכנים.
כמה עמודות — מופרדות בפסיקים:
UPDATE students
SET name = 'Dana Cohen', age = 25, email = 'dana.cohen@mail.com'
WHERE id = 1;ערך שמחושב מהערך הקיים:
UPDATE products SET stock = stock - 1 WHERE id = 3;“המלאי החדש = המלאי הנוכחי פחות 1”. (כמו x = x - 1 ב-Python.)
WHERE — חובה!
UPDATE students SET age = 25;בלי WHERE, התנאי חל על כל השורות: כל הסטודנטים עכשיו בני 25. אין “אתה בטוח?”, ואין Undo. (אחרי commit, הנתונים הישנים אבדו.)
הרגל של מקצוענים: לפני הרצה ידנית של UPDATE או DELETE, מריצים SELECT עם אותו WHERE בדיוק, ובודקים אילו שורות יושפעו. רק אחר כך מחליפים את SELECT ב-UPDATE.
UPDATE ... WHERE id = 1 = לוקחים את התיק מספר 1 מהארון, מוחקים את הגיל וכותבים גיל חדש. UPDATE בלי WHERE = לעבור על כל התיקים בארון ולשנות את הגיל בכולם, כי שכחתם להגיד באיזה תיק מדובר.
rowcount — כמה שורות השתנו?
אחרי UPDATE מ-Python, ל-Cursor יש cursor.rowcount = מספר השורות שעודכנו בפועל:
| rowcount | משמעות |
|---|---|
1 | נמצאה השורה, והערכים בה השתנו ✓ |
0 | אף שורה לא השתנתה: אין סטודנט עם ה-id הזה — או שהערכים החדשים זהים לישנים |
UPDATE על id שלא קיים הוא לא שגיאה ב-SQL. הפקודה “הצליחה” ועדכנה 0 שורות.
שימו לב לשורה השנייה בטבלה: ב-MySQL, rowcount סופר רק שורות שבאמת השתנו. אם מעדכנים את הגיל של אבי ל-31, והוא כבר בן 31 — rowcount הוא 0, למרות שאבי קיים. לכן, כדי לדעת אם רשומה קיימת (בשביל ה-404 של PUT), הדרך הבטוחה היא לשלוף אותה (SELECT ... WHERE id = %s) ולבדוק אם חזר None.
תחביר
UPDATE table_name
SET column_a = value_a, column_b = value_b
WHERE id = 7;cursor = connection.cursor()
cursor.execute(
"UPDATE students SET name = %s, age = %s WHERE id = %s",
(new_name, new_age, student_id),
)
connection.commit()
cursor.rowcount # 1 = changed, 0 = nothing changedשימו לב לסדר הפרמטרים: הם הולכים לפי הסדר של ה-%s בשאילתה כולה: קודם ה-SET, ובסוף ה-id של ה-WHERE.
דוגמת קוד ראשונה
הטבלה לפני:
id | name | age | email
1 | Dana | 24 | dana@mail.com
2 | Avi | 31 | avi@mail.com
3 | Noa | 22 | noa@mail.comSELECT id, name, age FROM students WHERE id = 2;
UPDATE students SET age = 32 WHERE id = 2;
SELECT id, name, age FROM students WHERE id = 2;תוצאה:
id | name | age
2 | Avi | 31
id | name | age
2 | Avi | 32פירוק הקוד שורה אחר שורה
| שאילתה | מה קרה |
|---|---|
SELECT ... WHERE id = 2 | לפני: בודקים מה יש, ואיזו שורה תושפע. |
UPDATE students SET age = 32 WHERE id = 2 | רק השורה עם id 2 השתנתה. רק age. השם והאימייל נשארו. |
SELECT ... WHERE id = 2 | אחרי: מאמתים. |
דוגמה נוספת
עדכון מ-Python, עם rowcount, ושורה שלא קיימת. update_demo.py:
import mysql.connector
connection = mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
try:
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS students")
cursor.execute(
"CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, "
"age INT NOT NULL, email VARCHAR(100) NOT NULL UNIQUE)"
)
cursor.executemany(
"INSERT INTO students (name, age, email) VALUES (%s, %s, %s)",
[("Dana", 24, "dana@mail.com"), ("Avi", 31, "avi@mail.com"), ("Noa", 22, "noa@mail.com")],
)
connection.commit()
cursor.execute(
"UPDATE students SET name = %s, age = %s, email = %s WHERE id = %s",
("Dana Cohen", 25, "dana.cohen@mail.com", 1),
)
connection.commit()
print("Updated rows for id 1:", cursor.rowcount)
cursor.execute("UPDATE students SET age = %s WHERE id = %s", (40, 99))
connection.commit()
print("Updated rows for id 99:", cursor.rowcount)
cursor.execute("UPDATE students SET age = %s WHERE id = %s", (31, 2))
connection.commit()
print("Updated rows for id 2, same age:", cursor.rowcount)
cursor.execute("UPDATE students SET age = age + 1 WHERE age < %s", (30,))
connection.commit()
print("Birthday for everyone under 30:", cursor.rowcount, "rows")
cursor = connection.cursor(dictionary=True)
cursor.execute("SELECT id, name, age, email FROM students ORDER BY id")
for row in cursor.fetchall():
print(row)
finally:
connection.close()פלט:
Updated rows for id 1: 1
Updated rows for id 99: 0
Updated rows for id 2, same age: 0
Birthday for everyone under 30: 2 rows
{'id': 1, 'name': 'Dana Cohen', 'age': 26, 'email': 'dana.cohen@mail.com'}
{'id': 2, 'name': 'Avi', 'age': 31, 'email': 'avi@mail.com'}
{'id': 3, 'name': 'Noa', 'age': 23, 'email': 'noa@mail.com'}פירוק:
DROP TABLE IF EXISTS— כל הרצה מתחילה מטבלה ריקה (רק להדגמה!).executemany(sql, list_of_tuples)— מריצה את אותה שאילתה לכל tuple ברשימה. נוח להכנסת כמה שורות.- עדכון של 3 עמודות — 4 Placeholders: שלושה ל-
SETואחד ל-WHERE, באותו סדר ב-tuple. - id 99 —
rowcount = 0. בלי שגיאה. - id 2 עם אותו גיל — גם
rowcount = 0, למרות שאבי קיים! שום דבר לא השתנה. לכן “לא נמצא” בודקים עםSELECT, לא עםrowcount. age = age + 1 WHERE age < 30—WHEREיכול לבחור כמה שורות. דנה (25, אחרי העדכון) ונועה (22) מתחת ל-30, ולכןrowcount = 2. אבי לא השתנה.connection.cursor(dictionary=True)— Cursor חדש, כדי לקבל את השורות בסוף כמילונים.
טעות נפוצה
הטעות 1 (הגדולה): UPDATE בלי WHERE.
cursor.execute("UPDATE students SET email = %s", (new_email,))כל הסטודנטים מקבלים את אותו אימייל. (כאן, בזכות UNIQUE, המסד דווקא יסרב, כי שני סטודנטים לא יכולים לקבל אותו אימייל. אילוצים מצילים! אבל על age לא היה אילוץ שיעצור.) לבדוק כל UPDATE: איפה ה-WHERE?
הטעות 2: סדר פרמטרים לא נכון.
cursor.execute("UPDATE students SET age = %s WHERE id = %s", (student_id, new_age))עכשיו מעדכנים את הסטודנט עם ה-id שווה לגיל, לגיל שווה ל-id. אין שגיאה, וזה Logical Error קשה מאוד למציאה. הסדר ב-tuple = הסדר של ה-%s בשאילתה, משמאל לימין.
הטעות 3: לחשוב ש-UPDATE על id לא קיים זורק שגיאה. הוא לא. קוד שלא בודק יחזיר “עודכן בהצלחה” על סטודנט שלא קיים. ולהפך: rowcount == 0 לא אומר בהכרח “לא קיים” — אולי פשוט שום ערך לא השתנה. בודקים קיום עם SELECT.
הטעות 4: לשכוח commit (כמו ב-INSERT). העדכון נראה בתוך אותו חיבור, ונעלם אחרי הסגירה.
סיכום
UPDATE table SET col = %s, col2 = %s WHERE id = %s— עדכון רשומה קיימת. ב-SET,=הוא השמה.- בלי
WHERE, כל השורות מתעדכנות. הרגל:SELECTעם אותוWHEREלפני הרצה ידנית. - ערך חדש יכול להיות מחושב:
stock = stock - 1. - מ-Python: פרמטרים לפי סדר ה-
%s(SET ואחר כך WHERE), ו-commit. cursor.rowcount= כמה שורות השתנו. 0 = לא קיימת, או שום ערך לא השתנה. את ה-404 של PUT קובעים עםSELECTשמחזירNone.
דוקומנטציה רשמית
- MySQL — UPDATE — עדכון לפי WHERE
- MySQLConnection.commit() — שמירת השינוי
פרק שני: DELETE לפי id — מחיקת רשומה מ-SQL ומ-Python
מה נלמד?
DELETE = ה-D של CRUD: מחיקת רשומות.
- התחביר
DELETE FROM ... WHERE .... - DELETE בלי WHERE — מה הוא עושה, ואיך נמנעים ממנו.
- מחיקה מ-Python, ו-
rowcount. - מה קורה ל-id אחרי מחיקה.
למה צריך את זה?
משתמש מוחק חשבון, מנהל מוחק מוצר שהפסיק להימכר, סטודנט עוזב את הקורס. ב-API: DELETE /students/7 = DELETE FROM students WHERE id = 7. ומחיקה היא הפעולה היחידה ב-CRUD שאין ממנה חזרה: אחרי commit, הנתון לא קיים יותר.
הסבר מהבסיס
התחביר
DELETE FROM students WHERE id = 3;DELETE FROM students— מאיזו טבלה.WHERE id = 3— אילו שורות למחוק.- אין רשימת עמודות: מוחקים שורות שלמות, לא עמודות. (כדי “לרוקן” שדה, משתמשים ב-
UPDATE ... SET field = NULL.)
DELETE בלי WHERE
DELETE FROM students;מוחק את כל השורות בטבלה. הטבלה עצמה נשארת (ריקה), אבל כל הנתונים נעלמים. זו כנראה הפקודה ש"הרסה" הכי הרבה נתונים בהיסטוריה של התוכנה. אותו כלל כמו ב-UPDATE: SELECT עם אותו WHERE קודם.
rowcount — שוב
| rowcount אחרי DELETE | משמעות |
|---|---|
1 | נמחקה רשומה ✓ |
0 | אין רשומה עם ה-id הזה. לא שגיאה ב-SQL. ב-API → 404 |
מה קורה ל-id?
עם AUTO_INCREMENT, MySQL לא ממחזר id. אם מחקתם את סטודנט 3, והסטודנט הבא שנוסף מקבל 4 (ולא 3). למה זה טוב? כי אם id 3 היה עובר למישהו אחר, כל מה שהצביע על “סטודנט 3” (קישור, הזמנה, לוג) היה מצביע פתאום על אדם אחר.
כשאדם נפטר, מספר תעודת הזהות שלו לא עובר לתינוק שנולד. מספר שנתפס פעם, נשאר שייך לאותה רשומה לתמיד. “חורים” במספור (1, 2, 4, 5) הם תקינים ואפילו רצויים.
מחיקה רכה (Soft Delete) — ברמת היכרות
במערכות רבות לא מוחקים באמת. מוסיפים לטבלה עמודה כמו is_active — 1 = פעיל, 0 = “נמחק” — ו"מחיקה" היא בעצם UPDATE. כך אפשר לשחזר, ולשמור היסטוריה (למשל, הזמנות ישנות של לקוח שעזב נשארות תקינות).
| מחיקה רגילה (Hard Delete) | מחיקה רכה (Soft Delete) | |
|---|---|---|
| הפקודה | DELETE | UPDATE ... SET is_active = 0 |
| השורה | נעלמת מהטבלה | נשארת, רק מסומנת |
| שחזור | אי אפשר | UPDATE ... SET is_active = 1 |
| קריאה | SELECT רגיל | כל SELECT של רשימה מוסיף WHERE is_active = 1 |
ב-SQL:
-- the table has: is_active INT NOT NULL DEFAULT 1
-- "delete" = mark the row, do not remove it
UPDATE students SET is_active = 0 WHERE id = 3;
-- every read shows only active students
SELECT id, name FROM students WHERE is_active = 1;
-- 1 | Dana
-- 2 | Avi
-- restore = one more UPDATE
UPDATE students SET is_active = 1 WHERE id = 3;מ-Python — בדיוק כמו delete_student, רק עם UPDATE במקום DELETE:
def soft_delete_student(student_id):
connection = get_connection()
try:
cursor = connection.cursor()
cursor.execute(
"UPDATE students SET is_active = 0 "
"WHERE id = %s", (student_id,))
connection.commit()
return cursor.rowcount > 0
finally:
connection.close()DEFAULT 1 אומר שכל סטודנט חדש נוצר פעיל, בלי שצריך לכתוב את זה ב-INSERT. המחיר של מחיקה רכה: כל שאילתה שמציגה רשימה חייבת לזכור את WHERE is_active = 1, אחרת סטודנטים “מחוקים” יופיעו שוב. השבוע נשתמש ב-DELETE אמיתי, אבל טוב לדעת שהאפשרות קיימת.
תחביר
DELETE FROM table_name WHERE id = 7;cursor = connection.cursor()
cursor.execute("DELETE FROM students WHERE id = %s", (student_id,))
connection.commit()
cursor.rowcount # 1 = deleted, 0 = no such rowדוגמת קוד ראשונה
SELECT id, name FROM students WHERE id = 3;
DELETE FROM students WHERE id = 3;
SELECT id, name FROM students;תוצאה:
id | name
3 | Noa
id | name
1 | Dana
2 | Aviפירוק הקוד שורה אחר שורה
| שאילתה | מה קרה |
|---|---|
SELECT ... WHERE id = 3 | בדיקה מראש: מה עומד להימחק? נועה. |
DELETE FROM students WHERE id = 3 | השורה של נועה נמחקה, כולה. |
SELECT id, name FROM students | נשארו דנה ואבי. |
דוגמה נוספת
מחיקה מ-Python: rowcount, מחיקה כפולה, ו-id שלא ממוחזר. delete_demo.py:
import mysql.connector
connection = mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
try:
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS students")
cursor.execute(
"CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL)"
)
cursor.executemany("INSERT INTO students (name) VALUES (%s)", [("Dana",), ("Avi",), ("Noa",)])
connection.commit()
cursor.execute("DELETE FROM students WHERE id = %s", (3,))
connection.commit()
print("Deleted id 3:", cursor.rowcount, "row(s)")
cursor.execute("DELETE FROM students WHERE id = %s", (3,))
connection.commit()
print("Deleted id 3 again:", cursor.rowcount, "row(s)")
cursor.execute("INSERT INTO students (name) VALUES (%s)", ("Tom",))
connection.commit()
print("Tom got id:", cursor.lastrowid)
cursor.execute("SELECT id, name FROM students ORDER BY id")
print("Rows now:", cursor.fetchall())
finally:
connection.close()פלט:
Deleted id 3: 1 row(s)
Deleted id 3 again: 0 row(s)
Tom got id: 4
Rows now: [(1, 'Dana'), (2, 'Avi'), (4, 'Tom')]פירוק:
DROP TABLE IF EXISTS— כל הרצה מתחילה מטבלה ריקה (רק להדגמה!).[("Dana",), ("Avi",), ("Noa",)]— לכל שורה tuple של ערך אחד, ולכן פסיק אחרי כל שם.- מחיקה ראשונה ←
rowcount = 1. - מחיקה שנייה של אותו id →
rowcount = 0, בלי שגיאה. ב-API: הבקשה הראשונה מחזירה 204, והשנייה 404. - Tom קיבל 4, ולא 3.
AUTO_INCREMENTלא ממחזר. יש “חור” במספור, וזה תקין.
טעות נפוצה
הטעות 1: DELETE בלי WHERE.
cursor.execute("DELETE FROM students")
connection.commit()כל הסטודנטים נמחקו. בכל קוד שמכיל DELETE: איפה ה-WHERE, ומה הפרמטר שלו?
הטעות 2: WHERE שתופס יותר ממה שחשבתם.
DELETE FROM students WHERE name = 'Dana';אם יש שתי דנה, שתיהן נמחקות. מוחקים לפי Primary Key (id), שמובטח שהוא ייחודי. השם הוא לא מזהה.
הטעות 3: לשכוח commit. המחיקה “עובדת” בתוך החיבור, ונעלמת אחרי הסגירה. במקרה של מחיקה, זה דווקא “באג מציל”, אבל עדיין באג.
הטעות 4: לקרוא לרשומה אחרי שמחקתם אותה. get_student(id) אחרי מחיקה מחזיר None. אם הקוד מניח שהוא קיים (student["name"]), הוא יקרוס. לכן delete_student תחזיר True/False ולא את הסטודנט שנמחק.
סיכום
DELETE FROM table WHERE id = %s— מוחק שורות שלמות. אחרי commit, אין חזרה.- בלי WHERE נמחקות כל השורות. מוחקים לפי Primary Key, ובודקים עם SELECT לפני כן.
cursor.rowcount: 1 = נמחק, 0 = לא היה קיים, בלי שגיאה. ב-API: 204 / 404.AUTO_INCREMENTלא ממחזר id. “חורים” במספור הם תקינים.- Soft Delete (
is_deleted) היא חלופה נפוצה במערכות אמיתיות.
דוקומנטציה רשמית
- MySQL — DELETE — מחיקה לפי WHERE
- MySQLCursor.rowcount — כמה שורות נמחקו
תרגול
התרגילים מבוססים רק על מה שנלמד בשיעור הזה ובשיעורים שלפניו. נסו לבד, ורק אז פתחו את הפתרון.
תרגיל 1: UPDATE ב-SQL
כתבו פקודת SQL שמשנה את הגיל של הסטודנט ש-id שלו 2 ל-32. מה יקרה אם תשכחו את WHERE?
הצג פתרון
UPDATE students SET age = 32 WHERE id = 2;בלי WHERE, כל הסטודנטים בטבלה יקבלו גיל 32. WHERE הוא החלק הקריטי בפקודה — הוא קובע אילו שורות מתעדכנות.
תרגיל 2: UPDATE מ-Python ו-rowcount
בטבלה יש סטודנטית אחת — דנה (id 1, בת 24). צרו אותה כך:
import mysql.connector
connection = mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS students") # start clean, so ids start from 1
cursor.execute("CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT)")
cursor.execute("INSERT INTO students (name, age) VALUES ('Dana', 24)")
connection.commit()
connection.close()כתבו update_age(student_id, new_age) שמעדכנת עם פרמטרים, ומחזירה כמה שורות עודכנו (rowcount).
print("Updated rows for id 1:", update_age(1, 25))
print("Updated rows for id 99:", update_age(99, 40))פלט צפוי:
Updated rows for id 1: 1
Updated rows for id 99: 0הצג פתרון
import mysql.connector
def get_connection():
return mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
def update_age(student_id, new_age):
connection = get_connection()
try:
cursor = connection.cursor()
cursor.execute(
"UPDATE students SET age = %s WHERE id = %s", (new_age, student_id))
connection.commit()
return cursor.rowcount
finally:
connection.close()
setup = get_connection()
cursor = setup.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS students "
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT)")
cursor.execute("INSERT INTO students (name, age) VALUES ('Dana', 24)")
setup.commit()
setup.close()
print("Updated rows for id 1:", update_age(1, 25))
print("Updated rows for id 99:", update_age(99, 40))Updated rows for id 1: 1
Updated rows for id 99: 0rowcount הוא 0 כשאין שורה כזו — זו לא שגיאה. הקוד שקורא מחליט מה לעשות עם זה (למשל, 404). שימו לב: ב-MySQL, rowcount סופר רק שורות שבאמת השתנו — עדכון לאותו ערך בדיוק מחזיר גם הוא 0.
תרגיל 3: update_student
התחילו שוב מטבלה עם דנה בלבד (id 1, בת 24), כמו בתרגיל 2. כתבו update_student(student_id, name, age) שמעדכנת את שני השדות ומחזירה את הסטודנט המעודכן כמילון, או None אם הוא לא קיים.
print(update_student(1, "Dana Cohen", 26))
print(update_student(99, "Nobody", 1))פלט צפוי:
{'id': 1, 'name': 'Dana Cohen', 'age': 26}
Noneהצג פתרון
import mysql.connector
def get_connection():
return mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
def update_student(student_id, name, age):
connection = get_connection()
try:
cursor = connection.cursor(dictionary=True)
cursor.execute(
"UPDATE students SET name = %s, age = %s WHERE id = %s",
(name, age, student_id))
connection.commit()
cursor.execute("SELECT * FROM students WHERE id = %s", (student_id,))
return cursor.fetchone()
finally:
connection.close()
setup = get_connection()
cursor = setup.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS students "
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), age INT)")
cursor.execute("INSERT INTO students (name, age) VALUES ('Dana', 24)")
setup.commit()
setup.close()
print(update_student(1, "Dana Cohen", 26))
print(update_student(99, "Nobody", 1)){'id': 1, 'name': 'Dana Cohen', 'age': 26}
Noneאחרי העדכון שולפים את השורה מחדש: אם אין סטודנט כזה — fetchone() מחזיר None, באותה הסכמה כמו get_student. (לא מסתמכים כאן על rowcount, כי עדכון לאותם ערכים בדיוק מחזיר 0 — למרות שהסטודנט קיים.)
תרגיל 4: delete_student
בטבלה יש שלושה סטודנטים — דנה (1), אבי (2) ונועה (3). צרו אותה כך:
import mysql.connector
connection = mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
cursor = connection.cursor()
cursor.execute("DROP TABLE IF EXISTS students") # start clean, so ids start from 1
cursor.execute("CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))")
cursor.execute("INSERT INTO students (name) VALUES ('Dana'), ('Avi'), ('Noa')")
connection.commit()
connection.close()כתבו delete_student(student_id) שמחזירה True אם נמחקה שורה ו-False אם לא. מחקו את אותו סטודנט (נועה, id 3) פעמיים.
print(delete_student(3))
print(delete_student(3))פלט צפוי:
True
Falseהצג פתרון
import mysql.connector
def get_connection():
return mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
def delete_student(student_id):
connection = get_connection()
try:
cursor = connection.cursor()
cursor.execute("DELETE FROM students WHERE id = %s", (student_id,))
connection.commit()
return cursor.rowcount > 0
finally:
connection.close()
setup = get_connection()
cursor = setup.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS students "
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))")
cursor.execute("INSERT INTO students (name) VALUES ('Dana'), ('Avi'), ('Noa')")
setup.commit()
setup.close()
print(delete_student(3))
print(delete_student(3))True
Falseהמחיקה השנייה לא נכשלת — היא פשוט לא מוצאת שורה (rowcount = 0).
תרגיל 5: מה קורה ל-id שנמחק?
עם שלושה סטודנטים (1, 2, 3): מחקו את 3, הוסיפו את טום, והדפיסו את ה-id שלו ואת כל השורות.
פלט צפוי:
Tom got id: 4
[(1, 'Dana'), (2, 'Avi'), (4, 'Tom')]הצג פתרון
import mysql.connector
connection = mysql.connector.connect(
host="localhost", user="root", password="kodkod", database="school")
cursor = connection.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS students "
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))")
cursor.execute("INSERT INTO students (name) VALUES ('Dana'), ('Avi'), ('Noa')")
connection.commit()
cursor.execute("DELETE FROM students WHERE id = %s", (3,))
cursor.execute("INSERT INTO students (name) VALUES (%s)", ("Tom",))
connection.commit()
print("Tom got id:", cursor.lastrowid)
cursor.execute("SELECT id, name FROM students ORDER BY id")
print(cursor.fetchall())
connection.close()Tom got id: 4
[(1, 'Dana'), (2, 'Avi'), (4, 'Tom')]עם AUTO_INCREMENT, id לא חוזר לשימוש. זה חשוב: אם משהו אחר עדיין מצביע על id 3 (למשל הזמנה ישנה), הוא לא יצביע בטעות על טום.