Ga naar hoofdinhoud

Verwijderen met del

Wat je opslaat, blijft staan tot je het weghaalt. Een bericht in een gastenboek dat weg moet, een account dat iemand opheft: daarvoor haal je een sleutel uit de database. Je oefent weer met mijn_data.db. Staat de leeftijd er niet meer in, draai dan eerst test_db.py uit Gegevens opslaan met SqliteDict.

Een sleutel weghalen​

Met del haal je een sleutel weg, met zijn waarde. Vervang de inhoud van proef_db.py door:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
if "leeftijd" in db:
del db["leeftijd"]
db.commit()
print("Leeftijd verwijderd")
else:
print("Er was geen leeftijd")
  1. Regel 4:

    Eerst kijken of hij er is, met in uit Bestaat de sleutel? in en get. Zonder die regel krijg je een KeyError als hij al weg is.

  2. Regel 5-6:

    del is een wijziging, net als opslaan. Ook hier schrijft pas db.commit() hem naar het bestand.

Voorspel
Je draait dit script twee keer na elkaar. Wat print het de eerste keer, en wat de tweede keer?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Draai het twee keer en kijk of je voorspelling klopte. Draai daarna bekijk_db.py: de leeftijd staat er niet meer in.

Test jezelf. In mijn_data.db staan naam en leeftijd. Je draait dit script:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
del db["leeftijd"]
db.commit()
print("Leeftijd verwijderd")
Controlevraag
Het script print Leeftijd verwijderd. Wat laat bekijk_db.py daarna zien?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Er gaat iets mis​

KeyError bij verwijderen​

KeyError: 'leeftijd'

Oorzaak: je verwijdert een sleutel die er niet (meer) is. Dat gebeurt als je hetzelfde script twee keer draait, of als iemand op een website twee keer op Verwijderen klikt.

Oplossing: kijk eerst met in:

# FOUT: crasht de tweede keer
del db["leeftijd"]

# GOED
if "leeftijd" in db:
del db["leeftijd"]
db.commit()

Je verwijderde sleutel is terug​

Na del print je script dat de leeftijd weg is, maar bekijk_db.py laat hem nog zien.

Oorzaak: db.commit() ontbreekt na de del. Zodra het with-blok sluit, gooit SqliteDict het verwijderen weg, net als een gewone wijziging zonder commit.

Oplossing: zet db.commit() direct onder de del, binnen het with-blok.

Opdrachten​

Opdracht 1: Predict - Hoeveel sleutels?​

Je database heeft de sleutels naam, leeftijd en woonplaats. Je draait dit:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
del db["woonplaats"]
db["hobby"] = "voetbal"
db.commit()

with SqliteDict("mijn_data.db") as db:
print(len(db))
print("Woonplaats" in db)
Voorspel
Welke twee regels print dit, van boven naar beneden?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Opdracht 2: Run​

Draai proef_db.py uit deze les twee keer, en daarna bekijk_db.py. Draai dan test_db.py en nog een keer proef_db.py. Wat print proef_db.py die laatste keer?

Antwoord

Leeftijd verwijderd. test_db.py heeft de leeftijd teruggezet, dus er is weer iets om te verwijderen. Daartussen liet bekijk_db.py een database zonder leeftijd zien.

Opdracht 3: Investigate - Zonder in​

Draai eerst test_db.py uit de eerste les, zodat de leeftijd er weer staat. Vervang dan de inhoud van proef_db.py door deze versie zonder in, en draai hem twee keer:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
del db["leeftijd"]
db.commit()
print("Leeftijd verwijderd")

Wat zie je de tweede keer, en op welke regel stopt het script?

Antwoord

De tweede keer stopt het met KeyError: 'leeftijd', op de regel met del. De leeftijd was de eerste keer al weg. Staat er ook de eerste keer al een KeyError, dan had je hem eerder in deze les al verwijderd: draai test_db.py en probeer het opnieuw. Leeftijd verwijderd print het na de fout niet meer: Python stopt bij de fout en voert de regels eronder niet uit.

Opdracht 4: Modify - Jij kiest wat weg moet​

Pas proef_db.py aan: het vraagt met input() welke sleutel weg moet, en verwijdert die. Is de sleutel er niet, dan print het Er was geen met de sleutel erachter.

Tip

Zet wat input() teruggeeft in een variabele, en gebruik die variabele overal waar nu "leeftijd" staat.

Antwoord
from sqlitedict import SqliteDict

sleutel = input("Welke sleutel moet weg? ")

with SqliteDict("mijn_data.db") as db:
if sleutel in db:
del db[sleutel]
db.commit()
print(sleutel, "verwijderd")
else:
print("Er was geen", sleutel)

Typ je twee keer hobby, dan print het eerst hobby verwijderd en daarna Er was geen hobby.

Door naar Een dictionary als waarde.