Ein Schema erstellen, Daten importieren und das Schema weiterentwickeln · Übung
Jede neue Zeile importieren oder keine
Du hast jetzt eine vollständige Liste validierter Tupel, bevor eine Datenbank berührt wird. Die nächste Grenze erhält diese vorbereitete Liste und eine vom aufrufenden Code verwaltete Verbindung:
import_staged_items(connection, staged_items)
Vervollständige diese Funktion in catalog_import.py. Setze die gesamte Schleife in einen Block with connection: und führe das feste INSERT über fünf Platzhalter aus. Zähle jede erfolgreiche Einfügung und gib dann (inserted, 0) zurück, nachdem die Transaktion festgeschrieben wurde. Verwende kein executemany, setze keine Werte in SQL ein, schreibe nicht innerhalb der Schleife fest und schließe die übergebene Verbindung nicht.
Run behält eine feste Abfolge bei, während du beide Varianten dieser Funktion baust:
== 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
Die wiederholten Aufrufe scheitern vorerst, weil diese erste Variante nur ausschließlich neue Zeilen akzeptiert. Das ist ein nachvollziehbares Zwischenergebnis. Das wichtige Verhalten zeigt sich, wenn nach einer früheren Einfügung im selben Aufruf ein Konflikt auftritt: Der Kontextmanager rollt den gesamten Versuch zurück. Nach dem erneuten Öffnen der Datei darf keine frühere neue Zeile dieses Aufrufs übrig bleiben.
Lass sqlite3.IntegrityError weiterlaufen. Diese Funktion hat noch nicht genug Regeln, um zu erklären, ob eine bestehende Zeile ein exakter Wiederholungsversuch oder eine Abweichung ist. Sie soll diese fehlende Regelung nicht hinter einer allgemeinen Erfolgsmeldung verbergen.
Eine Transaktion beschreibt ein nützliches gemeinsames Ergebnis. Für diese Funktion ist das der vollständige vorbereitete Datenstapel, nicht jede einzelne Zeile. Die Verbindung offen zu lassen hält auch die Verantwortung klar: Der aufrufende Code hat sie übergeben und entscheidet, wann ihr Lebenszyklus endet.
Nach Erfolg sollte die Verbindung außerhalb einer Transaktion sein, und eine andere Verbindung sollte jede eingefügte Zeile sehen.
Aufgabe
Vervollständige import_staged_items(connection, items) in catalog_import.py.
Füge jedes validierte Tupel mit der festen Platzhalteranweisung innerhalb eines Verbindungskontexts ein. Gib nach Erfolg (inserted_count, 0) zurück. Ein späterer Konflikt muss jede frühere Einfügung dieses Aufrufs zurückrollen, und die Verbindung des aufrufenden Codes muss offen bleiben.