Meerdere wijzigingen, één uitkomst · oefening
Weiger een tweede actieve uitlening
Het schema staat meerdere uitleenrijen voor één voorwerp toe, omdat afgeronde rijen waardevolle geschiedenis zijn. Dat betekent ook dat het schema op zichzelf twee actieve rijen toestaat. De uitleenbewerking moet de tweede weigeren.
Open transactions.py. De nieuwe checkout_loan(connection, loan) ontvangt één tuple met vier waarden en heeft de transactie en insert al. Voer vóór de insert de meegeleverde query voor een actief voorwerp uit met (item_id,) en haal één eventuele rij op.
Als er een rij aanwezig is, werp dan precies deze fout op:
raise ValueError("That item is already checked out.")
Houd de controle binnen with connection: naast de insert, zodat een weigering via hetzelfde foutpad naar buiten gaat als een insertfout. Afgeronde geschiedenis voldoet niet, omdat de waarde van returned_on aanwezig is.
Dit programma verwerkt één uitleen tegelijk. Met de verbindingsinstellingen die we hier gebruiken, begint het binnengaan van with connection: op zichzelf geen transactie; de eerste insert begint die. De eerdere leesactie reserveert het voorwerp niet. Twee programma’s die tegelijk schrijven, zouden extra bescherming nodig hebben om te voorkomen dat ze allebei het voorwerp als beschikbaar zien.
De functie moet databaseconstraints nog steeds hun werk laten doen bij ontbrekende bovenliggende ID’s of een dubbel uitleen-ID. Vang die fouten niet op en vervang ze niet door de melding over een actief voorwerp. Als er geen actieve rij overeenkomt, voer je de vaste gebonden insert uit, laat je de context committen en geef je het expliciete loan_id uit de tuple terug.
Druk op Run. De eerste vaste aanroep gebruikt voorwerp 1, dat al actieve uitlening 501 heeft, en hoort dit te tonen:
ValueError: That item is already checked out.
In een aparte database leent Sam de beschikbare voorwerpen 4 en 5. Beide slagen momenteel, omdat de functie het voorwerp beschermt, niet de limiet van het lid. Na heropenen is Sams actieve aantal 3. Dat zichtbare resultaat boven de limiet toont de tweede regel die de bewerking nog nodig heeft.
Submit test een actief voorwerp, een voorwerp met alleen afgeronde geschiedenis en een nooit uitgeleend voorwerp. Het geeft datumtekst die op SQL lijkt als gewone gegevens door en gebruikt ID’s die niet in de opdracht staan. Het controleert ook of ontbrekende voorwerpen en leden nog steeds sqlite3.IntegrityError veroorzaken, geslaagd werk na heropenen zichtbaar is en de meegegeven verbinding open blijft.
Opdracht
Maak de controle op een actief voorwerp in checkout_loan(connection, loan) af. Zoek binnen dezelfde verbindingscontext naar het voorgestelde item_id met returned_on IS NULL.
Als er een rij bestaat, werp dan ValueError("That item is already checked out.") op. Voeg anders de gebonden tuple in, commit door de context normaal te verlaten, geef het uitleen-ID terug en laat de verbinding open.