🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
10 messages
10 total messages Started by Mirosław Thu, 10 Sep 2009 09:15
Django i priorytety zapisu do bazy
#26812
Author: Mirosław
Date: Thu, 10 Sep 2009 09:15
24 lines
2354 bytes
Witam,

Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
(dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
tabeli korzystają też inne aplikacje, które w pewnych momentach,
pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
aplikacja. Jak najłatwiej ustrzec się tego błędu (w Django)?
Wiem, że problem jest bardziej od strony algorytmicznej tudzież
architektonicznej, pewnie jeszcze sprawa normalizacji tabel też by się
znalazła, aczkolwiek, dane które można by przenieść do powiązanej
tabeli już przeniosłem, reszty nie mogę.
Pomyślałem sobie, czy nie może można robić jakieś zamków, semaforów
etc w Django, pytam bo mało znam ten farmework, a muszę z nim teraz
przez chwilę popracować.

Baza to PostgreSQL 8.3

Z góry bardzo dziękuję za pomoc.

Mirek.
Re: Django i priorytety zapisu do bazy
#26816
Author: Krzysztof Stachlewski
Date: Thu, 10 Sep 2009 10:40
22 lines
1923 bytes
Mirosław pisze:

> Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> tabeli korzystają też inne aplikacje, które w pewnych momentach,
> pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
> aplikacja. Jak najłatwiej ustrzec się tego błędu (w Django)?

Dodatkowa kolumna z numerem wersji danego wiersza + obsługa
konfliktów przy zapisywaniu, gdy się numery wersji nie zgadzają.

Ta obsługa będzie raczej ręczna - typu wyświetlasz userowi
że ktoś mu te dane "podstępnie" zmienił - teraz są takie, jego
są takie - "spróbuj jeszcze raz, cancel" :-)

Stach
-- 
http://stachlewski.info
Re: Django i priorytety zapisu do bazy
#26817
Author: Mirosław
Date: Thu, 10 Sep 2009 11:10
42 lines
2993 bytes
On 10 Wrz, 12:40, Krzysztof Stachlewski <st...@fr.pl> wrote:
> Mirosław pisze:
>
> > Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> > (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> > tabeli korzystają też inne aplikacje, które w pewnych momentach,
> > pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> > kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> > zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> > zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> > aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
> > aplikacja. Jak najłatwiej ustrzec się tego błędu (w Django)?
>
> Dodatkowa kolumna z numerem wersji danego wiersza + obsługa
> konfliktów przy zapisywaniu, gdy się numery wersji nie zgadzają.
>
> Ta obsługa będzie raczej ręczna - typu wyświetlasz userowi
> że ktoś mu te dane "podstępnie" zmienił - teraz są takie, jego
> są takie - "spróbuj jeszcze raz, cancel" :-)
>
> Stach
> --http://stachlewski.info

Dziękuję za odpowiedź.

Tak, mam w tabeli pole updated_date, po nim sobie "ręcznie" sprawdzam,
bo nic lepszego na razie nie wymyśliłem.

A takie pytanie:
Jeśli user edytuje dane formularzem wygenerowanym na podstawie modelu,
w którym wyłączę parę pól, to rozumiem, że nawet gdy będzie zapisywał
starymi danymi do już zaktualizowanych to te wyłączone dane nie będą
zaktualizowane i zostaną w takim stanie jak je te moje aplikacje
zewnętrzne zmodyfikowały?

A teraz na odwrót, jeśli wezmę:
e = MyModel.objects.get(pk=1)
e.some_data = 1
e.save()
to zostaną zaktualizowane wszystkie dane czy tylko "some_data"?

Mirek.
Re: Django i priorytety zapisu do bazy
#26818
Author: Krzysztof Stachlewski
Date: Thu, 10 Sep 2009 14:17
55 lines
3006 bytes
Mirosław pisze:

> Tak, mam w tabeli pole updated_date, po nim sobie "ręcznie" sprawdzam,
> bo nic lepszego na razie nie wymyśliłem.

No ja bym jednak stawiał na numer wersji, bo ta data, to się może
w jakimś skrajnym przypadku okazać identyczna dla dwóch kolejnych
transakcji i co wtedy...

> A takie pytanie:
> Jeśli user edytuje dane formularzem wygenerowanym na podstawie modelu,
> w którym wyłączę parę pól, to rozumiem, że nawet gdy będzie zapisywał
> starymi danymi do już zaktualizowanych to te wyłączone dane nie będą
> zaktualizowane i zostaną w takim stanie jak je te moje aplikacje
> zewnętrzne zmodyfikowały?

Raczej nie powinien ich ruszać. Bo przecież o nich nie wie.
Ale jak wstawisz nowy obiekt tego typu i zrobisz save,
to tamte niezdefiniowane w modelu pola zostaną wypełnione
domyślnymi wartościami na poziomie bazy.

> A teraz na odwrót, jeśli wezmę:
> e = MyModel.objects.get(pk=1)
> e.some_data = 1
> e.save()
> to zostaną zaktualizowane wszystkie dane czy tylko "some_data"?

Tutaj tylko some_data. ORM sobie trzyma wewnętrznie, które pola
były zmieniane i tylko na nich robi update.
Tylko, że jak ty chcesz robić takie fiku-miku ;-)
to:

Potrzebujesz zrobić:
UPDATE costam SET pole=wartosc WHERE nr_wersji=NNN;
następnie sprawdzić czy UPDATE zmienił jakąś krotkę,
i jeśli nie zmienił, to stwierdzić, że coś ci ją nadpisało/skasowało.
A tego w django chyba nie zrobisz ładnie.

Opcjonalnie otwierasz transakcję,
robisz najpierw SELECT ... FOR UPDATE.
Patrzysz sobie ręcznie czy wersja jest OK
i podejmujesz decyzję co dalej (byle szybko :-)
Albo zapisujesz nowymi wartościami,
albo kończysz transakcję
niczego nie zmieniając i wywalasz błąd userowi.

To już chyba jest wspierane przez Django.
Nie jestem pewien, ale jakiś ticket znalazłem:
http://code.djangoproject.com/ticket/2705

No tyle, że robisz w sumie niepotrzebny SELECT.

Stach
-- 
http://stachlewski.info
Re: Django i priorytety zapisu do bazy
#26811
Author: Bart Ogryczak
Date: Thu, 10 Sep 2009 15:42
15 lines
2064 bytes
On Sep 10, 11:15 am, Mirosław <miroslaw....@gmail.com> wrote:
> Witam,
>
> Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> tabeli korzystają też inne aplikacje, które w pewnych momentach,
> pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
> aplikacja.

Użyj transakcji. W takich przypadkach baza ci pojedzie wyjątkiem
IntegrityError.
Re: Django i priorytety zapisu do bazy
#26813
Author: Krzysztof Stachlewski
Date: Thu, 10 Sep 2009 16:01
26 lines
1996 bytes
Bart Ogryczak pisze:
> On Sep 10, 11:15 am, Mirosław <miroslaw....@gmail.com> wrote:
>> Witam,
>>
>> Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
>> (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
>> tabeli korzystają też inne aplikacje, które w pewnych momentach,
>> pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
>> kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
>> zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
>> zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
>> aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
>> aplikacja.
> 
> Użyj transakcji. W takich przypadkach baza ci pojedzie wyjątkiem
> IntegrityError.

Rozwiń, proszę.

Transakcja nic tu nie daje. Chyba, że na poziomie serialized
*i* jeśli do tego będziesz ją trzymał cały czas otwartą
w trakcie gdy user edytuje sobie te dane.

Stach
-- 
http://stachlewski.info
Re: Django i priorytety zapisu do bazy
#26815
Author: Krzysztof Stachlewski
Date: Thu, 10 Sep 2009 16:03
9 lines
1139 bytes
Krzysztof Stachlewski pisze:

> Transakcja nic tu nie daje. Chyba, że na poziomie serialized

[poprawka] Oczywiście miało być "serializable".

Stach
-- 
http://stachlewski.info
Re: Django i priorytety zapisu do bazy
#26814
Author: Bart Ogryczak
Date: Thu, 10 Sep 2009 20:15
29 lines
2570 bytes
On Sep 10, 6:01 pm, Krzysztof Stachlewski <st...@fr.pl> wrote:
> Bart Ogryczak pisze:
>
> > On Sep 10, 11:15 am, Mirosław <miroslaw....@gmail.com> wrote:
> >> Witam,
>
> >> Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> >> (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> >> tabeli korzystają też inne aplikacje, które w pewnych momentach,
> >> pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> >> kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> >> zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> >> zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> >> aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
> >> aplikacja.
>
> > Użyj transakcji. W takich przypadkach baza ci pojedzie wyjątkiem
> > IntegrityError.
>
> Rozwiń, proszę.
>
> Transakcja nic tu nie daje. Chyba, że na poziomie serialized
> *i* jeśli do tego będziesz ją trzymał cały czas otwartą
> w trakcie gdy user edytuje sobie te dane.

No niestety, jak chce się mieć gwarancje spójności to do tego się
sprowadza.
Ewentuajnie można zrobić tak jak w Tracu -- wykrywać, że zostało
zmienione i nie pozwalać userowi na zapisanie.
Re: Django i priorytety zapisu do bazy
#26820
Author: Wojciech Malinowski
Date: Thu, 10 Sep 2009 20:47
20 lines
1814 bytes
Mirosław wrote:
> Witam,
> 
> Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> tabeli korzystają też inne aplikacje, które w pewnych momentach,
> pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> aplikacja.

Jak na razie wszyscy proponowali blokowanie optymistyczne
http://martinfowler.com/eaaCatalog/optimisticOfflineLock.html
W zależności od tego jak dokładnie działa Twoja aplikacja możesz też
spróbować blokowania pesymistycznego (z ewentualnym time-outem)
http://martinfowler.com/eaaCatalog/pessimisticOfflineLock.html

Pozdrawiam,
Wojciech Malinowski
Re: Django i priorytety zapisu do bazy
#26819
Author: forgems
Date: Thu, 10 Sep 2009 21:39
66 lines
3895 bytes
On Sep 10, 1:10 pm, Mirosław <miroslaw....@gmail.com> wrote:
> On 10 Wrz, 12:40, Krzysztof Stachlewski <st...@fr.pl> wrote:
>
>
>
>
>
> > Mirosław pisze:
>
> > > Mam taki problem. Otóż jest tabela z której korzystają użytkownicy
> > > (dodają nowe rekordy, modyfikują i zapisują rekordy) z tej samej
> > > tabeli korzystają też inne aplikacje, które w pewnych momentach,
> > > pobierają jakiś rekord robią krótkie obliczenia i zapisują go z
> > > kilkoma zmienionymi wartościami. Załóżmy teraz, że przed tym jak taka
> > > zew. aplikacja pobrała te dane, jakiś użytkownik pobrał je wcześniej i
> > > zaczął je edytować zapisując do bazy po tym jak zrobiła to zew.
> > > aplikacja. Sprawa oczywista - tracę ważne dane które wniosła zew.
> > > aplikacja. Jak najłatwiej ustrzec się tego błędu (w Django)?
>
> > Dodatkowa kolumna z numerem wersji danego wiersza + obsługa
> > konfliktów przy zapisywaniu, gdy się numery wersji nie zgadzają.
>
> > Ta obsługa będzie raczej ręczna - typu wyświetlasz userowi
> > że ktoś mu te dane "podstępnie" zmienił - teraz są takie, jego
> > są takie - "spróbuj jeszcze raz, cancel" :-)
>
> > Stach
> > --http://stachlewski.info
>
> Dziękuję za odpowiedź.
>
> Tak, mam w tabeli pole updated_date, po nim sobie "ręcznie" sprawdzam,
> bo nic lepszego na razie nie wymyśliłem.
>
> A takie pytanie:
> Jeśli user edytuje dane formularzem wygenerowanym na podstawie modelu,
> w którym wyłączę parę pól, to rozumiem, że nawet gdy będzie zapisywał
> starymi danymi do już zaktualizowanych to te wyłączone dane nie będą
> zaktualizowane i zostaną w takim stanie jak je te moje aplikacje
> zewnętrzne zmodyfikowały?

Nie. Django przy wywolaniu metody save robi update na wszystkie pola
zdefiniowane w modelu.

>
> A teraz na odwrót, jeśli wezmę:
> e = MyModel.objects.get(pk=1)
> e.some_data = 1
> e.save()
> to zostaną zaktualizowane wszystkie dane czy tylko "some_data"?
>

Zostana zaktaulizowane wszystkie pola zdefiniowane w modelu django.
Jezeli chcesz aktualizowac tylko wybrane pola moze to robic za pomocą
metody update queryseta ( nie obiektu)
czyli .

MyModel.objects.filter(pk=1).update(some_data=1)


polecam pobawic sie  za pomoca : python manage.py shell
from django.db import connection
print connection.queries

Jezeli aplikacja jest w trybie debug to w connection.queries bedziesz
mial ostatnio wykonane przez django zapytania .
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads