Eindproject: een uitleenprogramma dat gegevens bewaart · oefening
Importeer de eerste voorwerpen zonder duplicaten
Een eerste import heeft twee nuttige resultaten: rijen die voor het eerst zijn ingevoegd en rijen die al aanwezig zijn en exact overeenkomen. De opdracht moet beide aantallen afdrukken, maar pas nadat de volledige CSV is gevalideerd en de databasetransactie is gecommit.
De zichtbare demo initialiseert eerst zijn tijdelijke catalogus. Daarna doet die precies deze aanroepen:
main(["import-items", str(database_path), str(csv_path)])
main(["import-items", str(database_path), str(csv_path)])
De demo schrijft de drie exacte startrijen naar csv_path in dezelfde tijdelijke map. Bij elke aanroep geeft argparse aan import_items_command een namespace met args.database en args.csv door. Voeg import_error_is_documented(error) en import_items_command(args) toe en zet deze tak in main:
def import_error_is_documented(error):
message = str(error)
if setup_error_is_documented(error):
return True
if message in (
"CSV file does not exist.",
"CSV must be UTF-8 text.",
"CSV is not valid.",
"CSV must contain at least one item row.",
"CSV headers must be exactly: id,asset_tag,name,category,loan_days.",
):
return True
for prefix in ("CSV row ", "CSV contains ", "CSV item "):
if message.startswith(prefix):
return True
return False
if args.command == "import-items":
return import_items_command(args)
Controleer Path(args.database).exists() voordat je iets met de CSV doet. Elke opdracht behalve init volgt deze regel. Als de database ontbreekt, meld je precies Error: Database does not exist. Run init first. op stderr en geef je 1 terug. De controle mag het genoemde bestand niet aanmaken, ook niet als de CSV bestaat.
Roep voor een bestaande database import_items_csv(args.database, args.csv) aan. Open de CSV niet zelf, parse geen rijen, voer geen SQL uit en herhaal de schemavoorbereiding niet in lending.py. Die functie bereidt de volledige CSV al voor, controleert de compatibiliteit, opent één geconfigureerde applicatieverbinding, voert één atomaire idempotente import uit en sluit wat ze opent.
Vang ValueError op en werp die opnieuw op wanneer import_error_is_documented de waarde False teruggeeft. Een gedocumenteerde ontbrekende CSV wordt Error: CSV file does not exist.; meldingen over validatie, afwijkingen en schemaweigering behouden hun bestaande tekst. Elke verwachte fout geeft 1 terug, laat stdout leeg en schrijft één regel naar stderr. Een losstaande ValueError of andere exception blijft doorgaan.
Pak bij succes (inserted, unchanged) uit. Druk pas af nadat de aanroep terugkeert:
Items inserted: N
Items unchanged: M
Geef daarna 0 terug. Door beide prints na de functieaanroep te houden, voorkom je dat een eerste regel die op succes lijkt al verschijnt wanneer een latere rij de transactie laat terugdraaien.
Druk op Run. Dezelfde CSV met drie rijen wordt twee keer geïmporteerd:
== import-items ==
First status: 0
Items inserted: 3
Items unchanged: 0
Second status: 0
Items inserted: 0
Items unchanged: 3
stderr: <empty>
Een grondige controle gebruikt ook een afwijking in een latere rij en nieuwe paden. Die bevestigt dat er geen rij uit een gedeeltelijk uitgevoerde import achterblijft en dat een programmeerfout niet wordt omgedoopt tot een importweigering.
Opdracht
Voeg de exacte functie import_error_is_documented(error) uit de instructies toe, voeg import_items_command(args) toe of maak die af en zet deze tak in main:
if args.command == "import-items":
return import_items_command(args)
Weiger een ontbrekende args.database voordat je import_items_csv(args.database, args.csv) aanroept. Druk bij succes Items inserted: N af, gevolgd door Items unchanged: M, en geef 0 terug. Meld alleen een ValueError die door de classificatiefunctie wordt geaccepteerd; werp elke andere opnieuw op en druk niets af vóór succes.