Struktura obiektów biznesowych

Technologia w jakiej stworzono Odoo wpływ na funkcjonalność systemu, ale też na jego wewnętrzną strukturę.

1) Jak już mogliśmy się przekonać – struktura bazy danych jest rozbudowywana poprzez dziedziczenie modeli. Sprawia to, że dużo rzadziej niż w tradycyjnej metodzie pojawiają się nowe tabele. Dlaczego programiści oprogramowania klient-serwer preferują dodawania nowych tabel? Załóżmy, że chcemy stworzyć bazę firm kateringowych w oparciu o bazę wszystkich naszych klientów. Mamy do wyboru dwa rozwiązania:

a) dodać pole „katering” do tabeli „klienci”,

b) stworzyć odrębną tabelę „katering” z odnośnikiem (kluczem obcym) do tabeli „klienci”.

Można podać wiele sensownych argumentów za rozwiązaniem b). Można tworzyć moduł obsługi firm kateringowych bez zmiany reszty kodu. Nie trzeba zmieniać istniejącej tabeli, a pole „katering” nie pojawi się przy wszystkich rekordach. Zmniejszamy ryzyko nieuprawnionego dostępu (nie chcemy by wszyscy użytkownicy wiedzieli kto ma katering) etc….

Wszystkie te argumenty tracą na znaczeniu. Współczesne bazy danych nie są tak wrażliwe na wielkość rekordu. W aplikacjach webowych użytkownik nie będzie raczej miał dostępu do bazy danych inaczej niż poprzez funkcje aplikacji (nad którymi w pełni panujemy). Natomiast zastosowany przez Odoo sposób dziedziczenia (zarówno formularzy jak i kodu) pozwala łączyć izolację już funkcjonującego kodu z rozbudową.

Dlatego w Odoo preferuje się rozwiązanie a) z powyższych dwóch możliwości (uzupełnianie istniejących modeli). Ma to wiele zalet:

  • uproszczenie struktury bazy danych;
  • unikanie powielania tego samego kodu (raz dodane właściwości obiektów są widoczne wszędzie);
  • szybsze zapytania (nie ma potrzeby tworzenia złączeń);
  • bardziej przejrzysty kod (funkcjonalność nie jest dzielona między moduły – jest w jednym miejscu),
  • łatwiejsza adaptacja do specyficznych potrzeb.

2) Stosowanie ORM ma swoje wady i zalety. Jedną z wad jest niemożność stosowania różnych nazw kluczy głównych. Wszystkie nazywają się id i kropka. W związku z tym klucz obcy nie może się nazywać tak jak odpowiadający my klucz główny. Powszechnie stosuje się konwencję polegającą na dodaniu przedrostka wskazującego na nazwę tabeli do której się odnosimy. Na przykład jeśli tabela osób zawiera odnośniki do tabeli zawierającej opisy firmy/kompanie to mamy osoba.komp_id = kompania.id. No chyba, że komp_id odnosi się do tabeli komputerów ;-). W Odoo pola tabel są równocześnie atrybutami modelu (opisanymi zazwyczaj parametrem string). Programista musi zachować jednoznaczność – bo to przecież identyfikatory w przestrzeni nazw obiektów. Stosuje się przy tym dłuższe identyfikatory, często związane z polami wyboru (takimi jak One2many). Trzeba tylko pamiętać, że w takim przypadku pole w obiekcie jest obiektem, a nie wartością skalarną (kluczem obcym). Dlatego spotykamy często zapis (odwołanie do wartości klucza obcego) podobny do tego:user_id.id.

Takie rozwiązanie gwarantuje wczytanie wszystkich niezbędnych danych bez zastanawiania się jak one są ze sobą powiązane.

3) Traktowanie obiektów modeli jak złożonej sieci (a nie tylko rekordu tabeli bazy danych zamienionego na obiekt) powoduje, że zapis takiego obiektu obejmuje zmiany w więcej niż jednej tabeli. Na przykład wprowadzając fakturę zakupu, wpisujemy nagłówek do tabeli account_invoice (która zawiera także faktury sprzedaży!) a wiersze do account_invoice_line. Równocześnie jednak zapisany zostaje odpowiedni dokument księgowy (account_move), a jego identyfikator pojawia się w kolumnie account_invoice.move_id. Mało tego! Ponieważ w modelu account.invoice zadeklarowano number = fields.Char(related='move_id.name')– w tabeli account_invoice pojawia się także numer odpowiadający polu name w tabeli account_move. Można to traktować jako złamanie zasady unikania redundancji w projektowaniu baz danych (ta sama wielkość w dwóch miejscach). Ma to jednak swoje uzasadnienie – nie tylko związane z szybkością odczytywania takich danych. Gdyby ktoś zmienił opis w bazie danych – w tabeliaccount_move – to w account_invoicepozostanie nie zmieniony numer. Czy to oznacza niespójność? Ten numer jest przecież taki jak w chwili wystawienia dokumentu! Jeszcze bardziej widoczne jest to w przypadku sprzedaży. Dokumenty przekazywane na zewnątrz powinny zachowywać stan taki jak w chwili wydania, nawet gdy zmieniamy z jakichś powodów dokumenty podrzędne. Zasada unikania redundancji staje się w takich przypadkach kontrowersyjna. Inna rzecz, że Odoo pilnuje aby takie zmiany nie miały miejsca – ale ich (poza systemem) dokonanie nie powoduje załamania się spójności systemu.