Valoare neschimbată în Postgres folosind ORM-ul Django

docker
python
postgresql
django

(Stanciu Bogdan Mircea) #1

Am întâmpinat o problemă ciudată ce se reproduce pe unul din serverele de test pe care lucrez.

Context:

  • Python 3.6 + Django 2.1 rulate în container Docker
  • Posgres 10.4 (Debian 10.4-1.pgdg90+1) instalat în sistem

Problema este că salvarea unei anumite valori nu funcționează.

customer = Customer.objects.filter(customer_id=customer).first()  # returneaza corect randul din db

  if not customer: # blocul ăsta este sărit, există customer
    logger.error("Handling event failed: No customer")
    return False, {'error': 'fail statement'}

  if customer.newly_created:  # aici valoarea este True
    customer.newly_created = False
    customer.save()  
    # de aici newly_created este False

    return True, {'success': 'success statement'}

În modelul Customer am definit un câmp newly_created = models.BooleanField(default=True). Obiectul returnat în blocul de mai sus a fost creat anterior,într-un alt proces, cu numeroase alte câmpuri.

În blocul prezentat returnez un customer și intenționez să îî modific valoarea acelui câmp. Nu pot rula codul prin debugger dar pot pune print-uri. Rândul corect este returnat, valoarea inițială este cea așteptată, după save apare valoarea nouă. Blocul se încheie cu un return iar valoarea returnată acolo nu mai este folosită nicăieri în cod. Valoarea lui newly_created nu este atinsă nicăieri decât aici.

Codul este rulat , primesc acel return așteptat (‘success’: ‘success statement’) dar când verific rândul în Postgres (prin cli) văd că modificarea nu a fost salvată, newly_created este True. :frowning:

Nu am vre un catch pe undeva, dacă era să crape ceva primeam un 500 error. Sper că nu există probleme cu methoda .save() a modelului Django. Din ce știu treburile astea sunt testate intensiv.

Am încercat și cu Customer.objects.filter(customer_id=customer).update(newly_created = False), aceeași problemă și aici.

Uneori totuși valoarea este schimbată, fără să fi făcut ceva special. Acest comportament se întâmplă pe un singur server. Am să mai încerc și alte medii dar totuși, unde este buba?

Dăcă mai rulez încă o dată acest bloc pentru același customer valoarea este modificată și in bd. Prima și a doua execuție sunt identice, dar salvarea este efectuată cu success doar la a doua. :dizzy_face: Aplicația depinde totuși de acea primă rulare când valoarea ar trebuii să devină False.

Vreo idee ce aș mai putea verifica? am rămas fără idei.


#2

Poti pune logging pe Django, inclusiv ORM, astfel incat sa vezi ce query-uri se executa (vezi https://stackoverflow.com/questions/971667/django-orm-how-to-view-or-log-the-executed-query#answer-11373691). E mai bine asa decat cu print.

Mie imi suna a problema cu tranzactii, poate se salveaza, apare apoi o exceptie, se face rollback si altceva iti inghite exceptia. E de investigat.


(Stanciu Bogdan Mircea) #3

Am logger implementat, dar print-ul a fost mai rapid de scris. Am primit o recomandare bună de la @Cosmin_Popescu, să monitorizez direct și db-ul cu un tail -f