Streaming de date de la PostgreSQL folosind Akka Streams, Akka Http si Doobie

Acest articol explica calatoria mea de 2 zile cu privire la construirea unei aplicatii de streaming folosind akka-stream-urile Akka Framework, baza de date postgres si minunata biblioteca JDBC a tiparelor numita Doobie.

Totul a inceput cu cadrul meu PHP preferat, pe care l-am folosit pentru a construi o interfata de administrare pentru o aplicatie online. Clientul a solicitat aplicatiei sa aiba o functionalitate pentru exportul unui set mare de date de personal in format CSV pentru evaluare / analiza offline. porno tunisie In primul rand, fiind un dezvoltator lenes, am mers direct folosind o biblioteca PHP excel, a fost destul de simplu sa lucrez cu, dar in cel mai scurt timp am avut provocari (in special cu memorie). Aceste provocari nu au fost destul de usor de rezolvat, detinand volumul mare de date de exportat si complexitatea interogarilor care nu au putut fi implementate intr-o singura instructiune SQL select.

Mi-am mutat rapid implementarea in instrumentele mele preferate pentru programarea zilnica (Akka Framework). porno a 3 Am inceput cu o minunata biblioteca scala-csv de la @tototoshi. Il serveste destul de bine, dar intervalul de timp pe care l-a luat aplicatia pentru a muta acest set mare de date din baza de date postgres intr-un fisier temporar de pe server si ulterior, timpul necesar pentru ca aplicatia sa descarce fisierul temporar prin browserul utilizatorului a fost nu era acceptabil si nici nu era practic pentru productie.

In cele din urma, aleg sa transmit aceste inregistrari direct din baza de date postgres catre browserul utilizatorului pe baza catorva criterii de cautare selectate de catre utilizatorul final (clientul). porno online

Implementarea mea

Procesul va fi destul de simplu in ceea ce priveste aceasta implementare in care datele sunt citite din 2 tabele ca fluxuri care vor fi un fisier descarcabil din browserul utilizatorului.

Diagrama logica a implementarii fluxurilor akka

Cateva dependente de adaugat la proiectul build.sbt sunt dupa cum urmeaza:

lazy val akkaHttpVersion = „10. vrai porno 0.11″



lazy val akkaVersion = „2.5. porno gaule 11″ libraryDependencies ++ = Seq (



„com.typesafe.akka” %% „akka-http”% akkaHttpVersion,



„com. porno belge typesafe.akka” %% „akka-http-spray-json”% akkaHttpVersion,



„com.typesafe. porno medecin akka” %% „akka-http-xml”% akkaHttpVersion,



„com.typesafe.akka” %% „akka-stream”% akkaVersion,



„org . cap d agde porno tpolecat „%%” doobie-postgres „%” 0.5.3 ”



)

Sa incepem prin definirea modelelor noastre de cazuri pentru tabelele bazei de date postgres

class caz Solicitant (



id: Int,



first_name: String,



nume: String,



other_names: Optiunea [String]



Pozitia: String) {def parse (): List [String] = List (



first_name,



numele,



other_names. chubby porno getOrElse ( „”) ,



pozitie)} clasa de caz Hobby-uri (



solicitant_id: Sir,



hobby: Sir)

Observati ca am adaugat o metoda de analiza in clasa cazului solicitantului, aceasta este necesara pentru a usura conversia randului bazei de date intr-o lista de siruri. Relatia dintre masa candidatului si cea a hobby-urilor este una la multe.

Dupa cum sa mentionat anterior, voi folosi Doobie pentru conexiunea la baza de date. porno luxure Doobie este un strat JDBC functional pur si simplu mort pentru Scala si Pisici . Nu este un ORM si nici nu este o algebra relationala; ofera pur si simplu un mod principial de a construi programe (si biblioteci de nivel superior) care utilizeaza JDBC. Pentru a afla mai multe despre cum sa compuneti interogari cu Doobie, accesati site-ul web. amour porno Acum, sa scriem interogarea noastra doobie pentru a prelua aceste inregistrari.

def getApplicantList (): IO [List [Solicitant]] = {



sql „” „selectati * dintre solicitanti



” „” .query [List [Solicitant]]



. naturiste porno



  • porno perfect
  • porno mia kalifa
  • rocco porno
  • sexo porno
  • chloe sanchez porno
  • porno cougars
  • porno punition
  • porno h
  • film complet porno
  • porno hardcore
  • desinhibition porno
  • tukif porno français
  • porno gay hetero
  • porno disney
  • film porno hard
  • porno hairy
  • porno gay francais
  • porno girl
  • film porno netflix
  • porno vint





stream



.compile.toList



. body swap porno transact (xa)



} def getApplicantWithHobbies (id: Int): IO [List [Hobbies]] = {



val query = sql „” „select * from



hobbies where candidate_id = $ id ” „” .query [List [Hobbies]].



. porno 1980 stream



.compile



.toList



. porno belle femme transact (xa)



}

Apoi, este sa implementati codul pentru akka-stream (Sursa si flux) si cel al rutei akka-http.

val hobbiesFlow: Flow [Applicant, List [String], NotUsed] = Flow [Applicant] .map {solicitant => getApplicantWithHobbies (solicitant. jennifer lopez porno id) .unsafeRunSync () meci {



caz x: List [Hobby] => solicitant.parse: + x. porno petit cul map (_. hobby) .mkString („,”)

caz _ => solicitant. daughter porno parse



}

val source = Source (getApplicantList.unsafeRunSync ())



.via (hobbiesFlow)



. film porno romantique map (x => ByteString (x.mkString („,”) + „\ n”))

Dupa cum puteti vedea, am implementat o sursa akka folosind metoda noastra getApplicantList si o singura etapa de flux care obtine iterativ hobby-urile fiecarui solicitant, o imbinam pentru a avea o singura lista de siruri si in cele din urma convertim lista in codificare UTF-8 folosind metoda ByteString .

In cele din urma, am setat cateva antete personalizate http in ruta noastra akka-http pentru a permite browserului utilizatorului final sa descarce fluxurile de inregistrari generate. alexandra daddario porno

anteturi val = List ( RawHeader („Content-Disposition”, s „atasament; nume de fisier = solicitant.csv”))

respondWithHeaders (headers) {



complete ( HttpEntity (ContentTypes.`text / csv (UTF-8) `, sursa))



}

rezumat

Traseul complet akka-http arata cam asa:

pathPrefix („solicitant-descarcare”) {



get { val source = Source (getApplicantList. unsafeRunSync ())



.via (hobbiesFlow)



.map (x => ByteString (x. mkString („,”) + „\ n”)) anteturi val = Lista ( RawHeader („Content-Disposition”, s „atasament; nume de fisier = solicitant.csv”))

respondWithHeaders (headers) {



complete ( HttpEntity (ContentTypes.`text / csv (UTF-8) `, sursa))



}



}



}

Cu aceste cateva linii de cod am reusit sa transmit cateva gigabyte de inregistrari catre client fara a fi fost un dezvoltator cu gat rosu 🙂

Multumiri mari lui @Hungai pentru ca ati luat timp pentru a revizui aceasta postare.

Simtiti-va liber sa ma contactati daca aveti nevoie de mai multe explicatii in acest sens.