W ostatnim wpisie udało mi się skutecznie połączyć z bazą danych. Jeszcze wcześniej stworzyłem działające ścieżki. Teraz przyszła pora by to wszystko połączyć w jedną całość.
Zmiany w klasie Events
Tak naprawdę najwięcej się zmieniło w pliku routes\events.py. Pierwsze co zrobiłem to rozdzieliłem dotychczasową klasę Events na dwie: Event i Events. Na pierwszy rzut oka może się to wydawać dziwne i niepotrzebne ale ma to swoje uzasadnienie. W klasie Events mamy do czynienia z więcej niż jednym obiektem wydarzenia, tutaj umieściłem endpointy dotyczące pobrania wszystkich rekordów oraz dodania nowego do istniejących. Natomiast w klasie Event będziemy operować na pojedynczym obiekcie tak więc w każdym przypadku będziemy potrzebowali jego numer id. Oprócz tego postanowiłem wykorzystać reqparse wbudowany w flask_restul aby pobierać dane przekazane w zapytaniu. Korzystanie z niego jest proste i sprowadza się do paru kroków:
- Zainicjowanie zmiennych oraz określenie co będzie nas interesowało w zapytaniu
parser=reqparse.RequestParser() parser.add_argument('start') parser.add_argument('end') parser.add_argument('title')
- W konkretnej metodzie pobranie zmiennych
args=parser.parse_args()
W ten sposób w zmiennej args mamy zdefiniowane przez nas pola.
Pobieranie danych
Operacje na danych wykonuje się przy pomocy metod udostępnianych przez SQLAlchemy. Aby pobrać dane z bazy danych korzystam z następujących konstrukcji:
nazwa_klasy.query.all() #pobranie wszytskich rekordów nazwa_klasy.query.get(id) #pobranie rekordu o danym id
Należy pamiętać że klasa, której tutaj używamy to jest nasza klasa reprezentująca wiersz w bazie danych(u mnie nazywana encją) a nie te których używamy w ścieżkach. Jednak samo pobranie danych się na tym nie kończy. Musimy jakoś je zwrócić i ja wykorzystam do tego JSONa który jest najpopularniejszy w ostatnich latach. Aby sparsować wyniki do pożądanego formatu napisałem w klasie encji prostą metodą do serializacji
def serialize(self): return{ 'id': self.id, 'start':self.start, 'end': self.end, 'title':self.title }
którą potem wykorzystałem przy zwracaniu danych
return jsonify([i.serialize()for i in events]) #podczas pobrania wszystkich rekordów return jsonify([event.serialize()]) #podczas pobrania jednego rekordu
Komunikacja z bazą danych
Na sam koniec zostawiłem jeszcze sam proces komunikacji z bazą danych. Ponieważ samo pobieranie danych nie jest wystarczające musimy mieć możliwość dodawania nowych oraz edycji i usuwania istniejących danych. Dokonujemy tego przy pomocy instancji SQLAlchemy(u mnie db) oraz kilku metod, które w paru słowach opiszę.
db.session.add(row) #dodanie nowego wiersza db.session.delete(row) #usunięcie wiersza db.session.query(EventsEntity).filter_by(id=id).update(value) #aktualizacja wiersza nową wartością db.session.commit() #zapisanie zmian w bazie danych
Bardzo ważna jest ta ostatnia linia ponieważ dopiero ona zapisuje nasze zmiany w bazie danych.
Teraz to się nie wydaje trudne ale w trakcie pisania miałem parę problemów. Najwięcej kłopotów sprawiło mi odpowiednia serializacja danych w obie strony tak aby poprawnie odczytać przekazane dane oraz odpowiednio zwrócić te dane do użytkownika. Teraz wrócę do reduxa aby połączyć działąjący serwrs REST z częścią frontową przy pomocy redux-saga.