0%

Maak een schema, importeer gegevens en ontwikkel het verder · oefening

Importeer alle nieuwe rijen of geen enkele

Je hebt nu een volledige lijst met gevalideerde tuples voordat een database wordt aangeraakt. De volgende functie ontvangt die voorbereide lijst en één verbinding die door de aanroeper wordt beheerd:

import_staged_items(connection, staged_items)

Maak deze functie in catalog_import.py af. Zet de volledige lus binnen één blok with connection: en voer de vaste INSERT uit via vijf placeholders. Tel elke geslaagde insert en geef daarna (inserted, 0) terug nadat de transactie is gecommit. Gebruik geen executemany, voeg waarden niet rechtstreeks in de SQL-tekst in, commit niet binnen de lus en sluit de meegegeven verbinding niet.

Run houdt één vaste reeks aan terwijl je beide versies van deze functie bouwt:

== import staged items ==
First call: import_staged_items(connection, staged_items)
First result: (3, 0)
1 | TL-100 | Cordless drill | tools | 7
2 | EV-200 | Folding table | events | 14
3 | EL-300 | Projector | electronics | 3
Exact-repeat call: import_staged_items(connection, staged_items)
Exact-repeat result: IntegrityError
Changed-row call: import_staged_items(connection, changed_items)
Changed-row result: IntegrityError
Items after reopening: 3

De herhaalde aanroepen mislukken voorlopig, omdat deze eerste versie alleen volledig nieuwe rijen accepteert. Dat is een eerlijk tussenresultaat. Het belangrijke gedrag is wat er gebeurt wanneer een conflict volgt op een eerdere insert in dezelfde aanroep: de contextmanager draait de volledige poging terug. Wanneer het bestand opnieuw wordt geopend, mag geen van de eerdere nieuwe rijen uit die aanroep achterblijven.

Laat sqlite3.IntegrityError doorgaan. Deze functie heeft nog niet genoeg regels om uit te leggen of een bestaande rij een exacte herhaling of een afwijking is. Ze mag dat ontbrekende beleid niet verbergen achter een algemene succesmelding.

Een transactie beschrijft één bruikbare uitkomst. Voor deze functie is die uitkomst de volledige voorbereide batch, niet elke afzonderlijke rij. De verbinding openhouden houdt ook de verantwoordelijkheid duidelijk: de aanroeper heeft haar meegegeven en bepaalt wanneer de levenscyclus eindigt.

Na succes moet de verbinding buiten een transactie staan en moet een andere verbinding elke ingevoegde rij kunnen zien.

Opdracht

Maak import_staged_items(connection, items) in catalog_import.py af.

Voeg elke gevalideerde tuple in met de vaste instructie met placeholders binnen één verbindingscontext. Geef (inserted_count, 0) terug na succes. Een later conflict moet elke eerdere insert uit die aanroep terugdraaien en de verbinding van de aanroeper moet open blijven.