Wybierz region
pl
  • PL
  • EN
Wydrukuj

Operacje na bazie CouchDB z wykorzystaniem języka Python

Już niedługo Święta Bożego Narodzenia, w związku z czym będziemy musieli zmierzyć się z ogromem przygotowań. Warto jednak w ferworze obowiązków znaleźć chwilę na oddech i z korzenną herbatą w dłoni rozgościć się na kanapie – dzisiaj bowiem weźmiemy pod lupę jeden z nierelacyjnych silników bazodanowych, jakim jest CouchDB.

Czym jest CouchDB?

CouchDB, to jednowęzłowa baza danych, działająca jak każda inna baza za wybranym serwerem aplikacji. Nie ma natomiast problemu z aktualizacją jej do klastra przy bardziej wymagających projektach. CouchDB umożliwia wtedy uruchamianie pojedynczego logicznego serwera bazy danych dowolnej liczbie serwerów lub maszyn wirtualnych. Klaster CouchDB poprawia konfigurację z jednym węzłem dzięki większej pojemności i wysokiej dostępności bez zmiany interfejsów API.

Z czym współpracuje?

Silnik bazodanowy korzysta z protokołu HTTP i formatu danych JSON. Jest kompatybilny z dowolnym oprogramowaniem, które je obsługuje. Współpracuje również z zewnętrznymi narzędziami, takimi jak serwery proxy HTTP, load balancery, a unikalny protokół replikacji CouchDB jest podstawą nowej generacji aplikacji „Offline First” dla aplikacji mobilnych i innych środowisk z wymagającą infrastrukturą sieciową. W zależności od ekosystemu mamy do czynienia z inną bazą Apache CouchDB - CouchDB jest stworzona dla serwerów, podczas gdy PouchDB służy dla mobilnym i stacjonarnym przeglądarkom internetowym, a Couchbase Lite jest wykorzystywana przez natywne aplikacje iOS i Android. Wszystkie z nich mogą bezproblemowo replikować dane między sobą. 

Z tą symboliczną dawką wiedzy możemy przejść, do „tego co tygryski lubią najbardziej”, czyli poznamy kilka z podstawowych operacji, na które możemy sobie pozwolić mając do czynienia z CouchDB.

Przygotowanie środowiska

Podstawowa zasada działania na bazie CouchDB zostanie przedstawiona z wykorzystaniem następujących narzędzi:

  • Python w wersji 3.10, który można pobrać z oficjalnej strony.
  • Docker, do znalezienia pod adresem.
  • Kontener w Docker, oparty na obrazie couchdb, dostępnego na stronie dockerhub.

 

Inicjalizacja CouchDB

Za pomocą polecenia docker pull couchdb pobieramy najbardziej aktualny obraz CouchDB oraz uruchamiamy go z wykorzystaniem polecenia:

docker run -d --name demo-couchdb 

-p 5984:5984

-e COUCHDB_USER=couchuser

-e COUCHDB_PASSWORD=1234 couchdb

Najlepszym sposobem zapewnienia konfiguracji obrazu couchdb jest dostarczenie niestandardowego pliku *.ini do CouchDB, najlepiej przechowywanego w katalogu C:\CouchDB (na platformie Windows – dla MacOS ścieżka wygląda inaczej).

Mając uruchomiony na Dockerze, musimy pamiętać, że obraz eksponuje CouchDB na porcie 5984, uruchamia wszystko jako użytkownik couchdb i obsługuje użycie woluminu platformy Docker dla danych w /opt/couchdb/data.

W powyższym poleceniu ustawiamy dane autoryzacyjne za pośrednictwem zmiennych COUCHDB_USER oraz COUCHDB_PASSWORD.

W związku z powyższym po przejściu w przeglądarce na adres http://localhost:5984/_utils powinna wyświetlić się strona logowania.

 

Możemy od razu utworzyć nową bazę. Przez wzgląd na to, że Święta za pasem, będzie to baza składników świątecznych ciast – którym mało kto jest w stanie się oprzeć ????

Środowisko Python

Do celów demonstracyjnych pozwolę sobie stworzyć prymitywny skrypt w języku Python – run.py, który mógłby być uruchamiany z poziomu wiersza poleceń za pomocą komendy python run.py.

Zanim przystąpimy do operacji na utworzonej bazie, warto zainstalować bibliotekę, która przyda się do wykonania skryptu: aiohttp, Wykorzystuje się ją do wykonywania asynchronicznych operacji HTTP.

Operacje, które można wykonać w komunikacji z serwerem CouchDB

  1. Tworzenie nowej bazy.

Alternatywnym sposobem pokazanego powyżej, jest utworzenie bazy danych za pomocą odpowiedniego żądania HTTP – w tym przypadku metody PUT.

Gdy przyjrzymy się tej funkcji, to zauważymy, że najpierw tworzona jest sesja z definicją odpowiednich danych autoryzacyjnych, a następnie w ramach tej sesji wykonywane jest żądanie PUT do endpointu /christmas-cakes. Serwer zwraca wtedy odpowiedź z kodem 201-Created oznaczającym, że tworzenie bazy zostało zakończone sukcesem.

W sytuacji, gdy próbujemy utworzyć bazę o istniejącej już nazwie, serwer zwraca błąd 412-Precondition failed. Na liście baz już jest widoczna nasza nowoutworzona baza.

  1. Dodanie dokumentu do bazy.

W bazie przechowywane są dokumenty mające postać JSONa. Każdy z nich posiada przypisany identyfikator _id oraz klucz _key.  W celu dodania nowego dokumentu, przydatna okazuje się następująca funkcja:

Ważne jest nadanie unikalnego identyfikatora, w przeciwnym wypadku serwer zwróci błąd 409-Conflict oznaczający, że próbujemy utworzyć dokument o istniejącym już w bazie identyfikatorze. Istotne okazuje się również odpowiednie przygotowanie danych, które chcemy przesłać, niepoprawne przetworzenie ich skutkuje błędem 400-Bad request, przez wzgląd na to, że akceptowalnym formatem jest JSON w postaci ciągu znaków string.

W celu weryfikacji poprawności wykonanej operacji, możemy wykonać wywołanie metody:

                       GET http://localhost:5984/_uuids    

Na co serwer odpowie w następujący sposób:

{"uuids":["1df83b6579dfb43ec2f8f921b40008ea"]}
Na liście zwróconych identyfikatorów znajdzie się ten, który został nadany naszemu dokumentowi ze składnikami sernika. Dla pewności warto zajrzeć do bazy, gdzie na liście dokumentów powinien się pojawić nasz plik z zawartością widoczną na poniższej ilustracji. Numer _rev został nadany automatycznie.

 

  1. Pobranie istniejącego w bazie dokumentu.

Mając identyfikator dokumentu znajdującego się w bazie, pobranie go to „bułka z masłem”.

Wystarczy wywołać metodę:

GET http://localhost:5984/christmas-cakes/{id_dokumentu_w_bazie}

W odpowiedzi serwer zwraca naszego JSONa.

  1. Aktualizacja dokumentu.

Chcąc zmienić dokument w CouchDB, najpierw ładuje się pełny dokument z CouchDB, wprowadzasz zmiany w strukturze JSON i zapisuje się całą nową wersję tego dokumentu z powrotem w CouchDB. Każda zmiana jest identyfikowana przez nową wartość _rev.

Podczas aktualizacji/usuwania dokumentu, CouchDB oczekuje, że zostało dołączone pole _rev wersji, którą chcemy zmienić. Gdy CouchDB zaakceptuje zmianę, wygeneruje nowy numer wersji. Mechanizm ten chroni przed nadpisywaniem danych, które zostały zmodyfikowane podczas próby modyfikacji przez nas. Kto pierwszy zapisze zmianę w dokumencie - tego zmiana jest widoczna w bazie. Gdy nie dostarczymy pola _rev, wtedy serwer zwróci błąd Document update conflict.

Załóżmy, że chcieliśmy zmodyfikować naszą listę składników na sernik:

{„ingredients”: [„lots of love”]}
Po wywołaniu funkcji z odpowiednimi parametrami faktycznie składniki te zostały zaktualizowane.

Replikacja CouchDB

Replikacja CouchDB stanowi mechanizm synchronizacji baz danych, który może tego dokonać lokalnie lub zdalnie. W prostym żądaniu POST informuje się CouchDB o źródle i celu replikacji - CouchDB wie, które dokumenty i nowe wersje dokumentów znajdują się w źródle, a które nie są jeszcze w miejscu docelowym. Następnie przejdzie do przeniesienia brakujących dokumentów oraz wersji.

Wnioski

W artykule przedstawiłam jedynie podstawowe operacje na CouchDB i jego możliwości. Ciekawym zagadnieniem są również widoki map/reduce i Design documents, niemniej zgłębianie wiedzy na ten temat pozostawiam Wam! ????


Joanna Maciak

Programistka. Specjalistka z ekipy Asseco Master Team. Interesuje ją szerokopojęty AI, machine learing oraz tematy z obszaru cybersecurity. Miłość no.1 - java, na drugim miejscu joga, podróże po Polsce, a czasem nawet szydełkowanie.


Wydrukuj