ޯuj ddlZddlZddlmZddlmZddlZddlZddlm Z m Z m Z m Z ee jjjjdz dz dz dz Zed z Zed z Zed z Zed z Zed z Zedz Zedz Zedz ZdZdZee jjjdz dz ZeZdZdZiddddddddddddddd dd!dd"dd#dd$dd%dd&dd'dd(dd)ddddddddddddd* Zd+d,d-d.d/d0d1d2d3d4d5d6d7d8d9Z d:d:d:d;d;d:dd?d@dAdBdBdCZ!ddDdddddddEddddF Z"dGdHdIdJdKdLdMZ#dNdOdPdQdPdRdMZ$ddDddEddSZ%dTdUdVdWdXZ&dOddńZ?e37dƦdDŽZ@e37dȦdɄZAe37dʦd˄ZBe37d̦d̈́ZCe37dΦdτZDe#e&e)e+dМZEdфZFeFZGe37dҦdӄZHe$e'e*e,dМZIdԄZJeJZKe37dզdքZLdׄZMd؄ZNdلZOdڄZPdۄZQd܄ZRd݄ZSdބZTd߄ZUddZVe"e%e(e-dМZWdZXdZYdZZe3=ddZ[e3=ddZ\e2dkre3]ddddddSdS)N) OrderedDict)Path)Flaskjsonifyrequestsend_from_directoryPYTHON MyICR_Suitelocal_dbparquetzprodotti.parquetzemesso.parquetzboxoffice.parquetzdiritti.parquetzdiritti_enrich.parquetz gemma.parquetz imdb.parquetz cast.parquetz 127.0.0.1idatagridsrcctjj}||dt|<t tt kr8tdt tt k8|S)NcolumnsrowsF)last)uuiduuid4hex_RESULTS_STORElen_RESULTS_STORE_MAXpopitem)rrtokens MC:\Users\Mauro Gagliardi\Dropbox\adrian\sandbox\powerbricks\backend\server.py_store_resultsr-sh JLL E(/>>N5 n   2 2 2E*** n   2 2 2 Lprodottointedizione program_idstringtitolo_italianotitolo_originaledescr_edizione unico_serialesuperserie_descr superserie_idsuperserie_extkeystagioneduratacromiaveg num_episodipaesi_produzione1paesi_produzione2) paesi_produzione3anno_produzionegenere1genere2genere3 provenienzavm tipologia imdb_codiceregistaattoriRIFERTIPOLTITOANNOPAESEGENEREEPISDURATA SUPERSERIEVEGIMDBREGISTAATTORI)r r:r%r&r4r1r5r0r-r)r/r;r<r=K=dF<nA)r r;r:r%r&r4r1r5r0r-r)r/r<r=datefloat) retedata_emissione ora_inizioora_fine durata_netta prima_visioneepisodioaudienceshare durata_lordar:fasciaRETEDATAINIZIOFASCIAAUDSHA)rWrXrYrar^r_-D7/2)r, data_debutto distributoreincasso spettatoriDEBUTTOINCASSO SPETTATORIz DIST. CINEMA)rmrorprnxr:d_t ragsoc_distrperc pass_cons pass_cons_totpass_eff pass_eff_totdecrscadcausale flag_inib decr_inib scad_inib contrattoriga situazione)fr_rrfornitore_cluster esclusivo_tem DISTRIBUTORE%zP.CONS.zP.EFF.zDECOR.zSCAD.zCAUS.)rvrwrxrzr|r}r~(a_statoa_ida_titoloa_dataa_distributore a_tipologiaa_tipoa_autore_registaa_casta_codice_prodotto a_episodio a_supportoa_note_supporto a_deadlinea_note_pubblichea_note_privatea_acquistato_vendutoa_c5a_i1a_r4a_la5a_i2a_irisa_topa_foca_c20a_ci34a_c27a_cina_infa_emoa_enea_coma_stoa_cria_actv_statov_rdav_c5v_i1v_r4v_la5v_i2v_irisv_topv_focv_c20v_ci34v_c27v_cinv_inf)v_emov_enev_comv_stov_criv_act=z<>ILIKEzIS NULLz IS NOT NULL)equals not_equalscontainsis_null is_not_null>=z<=BETWEEN) rrgtltgteltebetweenrrc*t|d}t|dkrt d|d|\}}}t |ddt |ddt |dS)uConverte una data in formato italiano GG/MM/AAAA (quello che l'utente scrive nel blocco) nel formato ISO YYYY-MM-DD della colonna gia' castata a VARCHAR — necessario perche' il confronto (>, <, BETWEEN...) e' lessicografico sulla stringa: funziona correttamente solo se entrambi i lati sono nello stesso formato ISO (l'ordine lessicografico coincide con l'ordine cronologico solo in quel formato)./zdata non valida: z (atteso GG/MM/AAAA)04d-02d)strstripsplitr ValueErrorr!)valuepartsdaymonthyears r_parse_date_valuers JJ     $ $S ) )E 5zzQJUJJJKKKC$ii = = =c%jj = = =s3xx = = ==rz ../frontend) static_folderstatic_url_pathSEND_FILE_MAX_AGE_DEFAULTcd|jd<|S)Nz#no-store, no-cache, must-revalidatez Cache-Control)headers)responses r _no_cachers(MH_% Orrc6tdS)Nz index.html)appsend_static_filerrindexrs    - --rz /vendor/datagrid/c,tt|SN)rDATAGRID_SRC_DIR)filenames rdatagrid_staticrs / : ::rz/api/results/c~t|}|tddidfSt|S)Nerrorz.risultati non trovati (scaduti o mai esistiti)i)rgetr)rresults r api_resultsrs@    & &F ~!QRSSUXXX 6??rz.workspace_state.jsonz/api/workspacectstdSttjtdS)Nutf-8encoding)WORKSPACE_STATE_PATHexistsrjsonloads read_textrrrapi_workspace_getrsL  & & ( (t}} 4:2<z$_fields_response..sE D%u{tT/J/JKKr)ritems) fields_dictrs `r_fields_responsersG &,,..  rz /api/fieldsc6tttSr)rFIELDSANAGRAFICA_LABELSrrr api_fieldsrs F$5 6 66rz/api/fields_emessoc6tttSr)r EMESSO_FIELDS EMESSO_LABELSrrrapi_fields_emessor s M= 9 99rz/api/fields_boxofficec6tttSr)rBOXOFFICE_FIELDSBOXOFFICE_LABELSrrrapi_fields_boxofficer$s ,.> ? ??rz/api/fields_dirittic6tttSr)rDIRITTI_FIELDSDIRITTI_LABELSrrrapi_fields_dirittir(s NN ; ;;rz/api/fields_gemmac6tttSr)r GEMMA_FIELDS GEMMA_LABELSrrrapi_fields_gemmar,s L, 7 77r)emesso boxofficedirittigemmactt}tD])\}}|D]\}}|||d|<*|SN_)dictr_SATELLITE_LABELSr)labelsdomain domain_labelsfieldrs r_build_output_labelsr:t # $ $F!2!8!8!:!:00 )//11 0 0LE5*/Ff&&u&& ' ' 0 Mrz /api/labelsc*ttSr)r OUTPUT_LABELSrrr api_labelsr> = ! !!rctt}tD])\}}|D]\}}|||d|<*|Sr2)r4ANAGRAFICA_WIDTHS_SATELLITE_WIDTHSr)widthsr7 domain_widthsr9widths r_build_output_widthsrFr;rz /api/widthsc*ttSr)r OUTPUT_WIDTHSrrr api_widthsrIr?rc|d}|d}|d}||vrtd|||}|dkrt}n|dkrt}nt}||vrtd|d|||}|r|d nd } |d krt nt } |d vr | d |d|gfS|dkr&|dkr d| d |dn| d |d } | d|dd|dgfS|dkrdt|dD} t| dkrtd|d|dkrtn| } | d |d| | d| | dgfS|dkr| d |d|d|gfS|dkr| d |d|dt|gfS| d |d|d| |gfS)Nr9oprzcampo non valido: r$rUzoperatore non valido per : .rrV)rr"z" rzCAST(z " AS VARCHAR) z ?rrc6g|]}|Sr)r)rps rrz!_build_filtro..Gs :::q:::r,'z2': between richiede due valori separati da virgolaz" BETWEEN ? AND ?r) rr OPS_STRINGOPS_DATEOPS_INTrVr!rrrr)noder table_aliasr9rKrropssql_opprefixcastercolrconvs r _build_filtrora!s HHW  E $B HHW  E K5e55666  E  & }}BUBBbBBCCC WF #. 5    2Fw&&UUCF ''',,5,,F,,b00 Z8=3f33u3333vL`L`X]L`L`L`"""""\\\\N22 Y::CJJ$4$4S$9$9::: u::??ZZZZ[[ [$)VOO  335333dd58nndd5QR8nn5UUU ..5..F...77 ..5..F...1B51I1I0JJJ * *u * * * * *VVE]]O ;;rcz|d}|dkrt|||S|dkrx|d}|dvrtd|t|dg||\}}|sdSdd |d |zd z|fStd |) NkindfiltrogrupporK)ANDORz operatore di gruppo non valido: children(rO)znodo non valido: )rrar _build_wherejoin)rYrrZrcrKrparamss r _build_nodernSs 88F  D xT; <<< x XXd^^ ] " "DDDEE E$TXXj"%=%={KXX v 4YYYY^^E***S0&88 /// 0 00rcg}g}|D]E}t|||}||\}}||||F||fSr)rnappendextend) nodesrrZclausesrmrYbuiltclause node_paramss rrkrkbsoG F##D+{;; = # v k"""" F?rc||dg}tt|dd|}|d}|tt}d|D}|rt d||st d|d}||d d }|d vrt d ||d}|tt }d |D} | rt d| |st d|dd} | dvrt d| |||dg| d}|d} | | d} | tt} d| D} | rt d| | st d| dd}|dvrt d|| | dg|d} |d}||d}|tt}d|D}|rt d||st d|dd}|dvrt d|||dg|d}|d }||d}|tt}d!|D}|rt d"||st d#|dd}|dvrt d$|||dg|d}||||| ||fS)%NfilterslimitrMfieldsc$g|] }|tv |Sr)rrfs rrz%_parse_query_body..vs;;;Q1F??q???rzcampi in output non validi: %nessun campo selezionato per l'outputr- aggregationtutte)primaultimarz aggregazione Emesso non valida: c$g|] }|tv |Sr)rr|s rrz%_parse_query_body..s"HHH1-1G1GQ1G1G1Grzcampi Emesso non validi: z,nessun campo Emesso selezionato per l'output join_typeauto)rleftinnerztipo di join non valido: )rrzrxrr.c$g|] }|tv |Sr)r"r|s rrz%_parse_query_body..s#NNN1A=M4M4MQ4M4M4Mrzcampi Boxoffice non validi: z/nessun campo Boxoffice selezionato per l'outputz#tipo di join Boxoffice non valido: )rzrxrr/c$g|] }|tv |Sr)r&r|s rrz%_parse_query_body..s"JJJ1!>2I2IQ2I2I2Irzcampi Diritti non validi: z-nessun campo Diritti selezionato per l'outputz!tipo di join Diritti non valido: r0c$g|] }|tv |Sr)r*r|s rrz%_parse_query_body..s"FFF10E0EQ0E0E0Erzcampi Gemma non validi: z+nessun campo Gemma selezionato per l'outputztipo di join Gemma non valido: ) rminr!listrrrr"r&r*)body max_limitrxry output_fieldsinvalidr-r emesso_fields invalid_err.boxoffice_fields invalid_b join_type_br/diritti_fields invalid_d join_type_dr0 gemma_fields invalid_g join_type_gs r_parse_query_bodyroshhy"%%G DHHWc**++Y 7 7EHHX&&MV ;;-;;;GCAAABBB B@AAA XXh  F  jj88 : : :M MMNN N 8,,   //MHH HHH  FDDDEE E MKLL LJJ{F33 5 5 5DDDEE E'#zz)R00"   %%I%==22  ##$455 NN 0NNN  IGIGGHH H PNOO OmmK88 7 7 7P;PPQQ Q' }}Y33$  hhy!!G!X..  !!.11NJJJJJ  GE)EEFF F NLMM Mkk+v66 7 7 7NNNOO O%{{9b11$   HHW  E  yy**   --LFF FFF  EC CCDD D LJKK Kii V44 7 7 7L{LLMM M#yyB//$   M5&)We KKrct|dgtd\}}|rdd|nd}t}|d}|dkr d |d |d }n|d krd nd}d|d|d|d}|dd}|dkrd} n|dkrd} n|rdnd} | d|d} dd|dD} | | |fS)u(JOIN su Emesso: 'prima'/'ultima' usano una window function per prendere la riga INTERA della prima/ultima emissione (non solo la data), 'tutte' e' un JOIN semplice (una riga per emissione, cambia cardinalita'). LEFT JOIN sempre: un prodotto senza emissioni resta comunque in output. I filtri Emesso (es. rete/tipologia) si applicano DENTRO la subquery, prima di scegliere prima/ultima — filtrare "prima emissione su Canale 5" deve restringere alle emissioni Canale 5 e poi prendere la piu' vecchia, non il contrario. rxNrZWHERE  AND rrrz(SELECT * FROM read_parquet('z') rjrASCDESCz( SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY prodotto, edizione ORDER BY data_emissione z< ) AS rn FROM read_parquet('z') z1 ) WHERE rn = 1 )rrr LEFT JOINr INNER JOINrOzA e ON a."prodotto" = e."prodotto" AND a."edizione" = e."edizione", c3(K|] }d|d|dVdS)ze."z " AS "emesso_rNNrr|s r z%_build_emesso_join..s6JJA/1//1///JJJJJJrrz)rkrrrlEMESSO_PARQUET_PATHas_posix) r-emesso_clauses emesso_paramsemesso_where_sql emesso_posixr emesso_fromorderjoin_type_choicerjoin_sqlcolss r_build_emesso_joinrs%1 9b!!=d%%%!NMCQX> ^ < <>>>VX&//11L'KgZlZZGWZZZ $//V  NS   %1   "    $zz+v666!! W $ $ $2CLL  J J{ J J J  99JJ9IJJJ J JD T= ((rct|dgtd\}}|rdd|nd}t}d|d|d }|d d }|d krd }n|dkrd}n|rdnd }|d|d}dd|dD} || |fS)uJOIN su Boxoffice: relazione 1:1 su 'prodotto' (verificato sui dati reali, 39.771 righe = 39.771 prodotti distinti) — a differenza di Emesso non serve ne' window function ne' scelta di aggregazione, un JOIN diretto basta e non cambia mai la cardinalita' del risultato. Stessa regola automatica LEFT/INNER di Emesso: con filtri Boxoffice presenti un prodotto senza corrispondenza deve uscire dal risultato (INNER), altrimenti Boxoffice arricchisce senza restringere (LEFT). rxNrrrrz( SELECT prodotto, stagione, CAST(data_debutto AS VARCHAR) AS data_debutto, distributore, incasso, spettatori FROM read_parquet('z ')  )rrrrrrrOz# bo ON a."prodotto" = bo."prodotto"rc3(K|] }d|d|dVdS)zbo."z" AS "boxoffice_rNNrr|s rrz(_build_boxoffice_join..As6QQ3A33q333QQQQQQrrz)rkrr"rlBOXOFFICE_PARQUET_PATHr) r. bo_clauses bo_params bo_where_sqlbo_posixbo_fromrrrrs r_build_boxoffice_joinrs%) i$$&6DJ ;EL6GLL44666"L%..00H %       G!}}[&996!! W $ $ $.?LLK JJgJJJH 99QQYx=PQQQ Q QD T9 $$rc T t|dgtd\}}|rdd|nd}t}t }hd dd hfd tD}d  fd |D}d |d|d|d|d }|dd} | dkrd} n| dkrd} n|rdnd} | d|d} d d|dD} | | |fS)uJOIN su Diritti: relazione 1:molti su prod+ediz (diritti) = prodotto+ edizione (Anagrafica) — nomi di colonna diversi tra le due tabelle, a differenza di Emesso/Boxoffice che condividono gia' "prodotto"/ "edizione". Nessuna window function/aggregazione (a differenza di Emesso): questo primo giro restituisce sempre tutte le righe diritto che soddisfano i filtri, la scelta di eventuale aggregazione e' rimandata insieme al resto della logica di business derivata (vedi DIRITTI_FIELDS). diritti_enrich.parquet e' agganciata qui dentro come tabella "sidecar" (LEFT JOIN 1:1 su id_diritto, verificato zero righe orfane in entrambe le direzioni) — non e' un dominio/blocco a se', i suoi due campi (fornitore_cluster, esclusivo_tem) sono semplicemente altri due campi di "Tabella Diritti" agli occhi dell'utente e del resto del backend. Stessa regola automatica LEFT/INNER di Emesso/Boxoffice (qui riferita all'insieme diritti+diritti_enrich): con filtri Diritti presenti un prodotto senza corrispondenza deve uscire dal risultato (INNER), altrimenti Diritti arricchisce senza restringere (LEFT). rxNrrrrr|r}rrrrcg|]}|v| Srrrr} enrich_colss rrz'_build_diritti_join..es#BBBaQk-A-A-A-A-Arrc3>K|]}|vr d|d|dnd|dVdSz CAST(dr."" AS VARCHAR) AS "rNzdr."Nrrr} date_colss rrz&_build_diritti_join..fs`   23i-A------[A[[[      rz#( SELECT dr.prod, dr.ediz, z, en."fornitore_cluster" AS "fornitore_cluster", CAST(en."ESCLUSIVO_TEM" AS VARCHAR) AS "esclusivo_tem" FROM read_parquet('z&') dr LEFT JOIN read_parquet('z3') en ON dr."id_diritto" = en."id_diritto" rrrrrrrrOz9 d ON a."prodotto" = d."prod" AND a."edizione" = d."ediz"c3(K|] }d|d|dVdS)zd."z" AS "diritti_rNNrr|s rrz&_build_diritti_join..~s6LLQ0100A000LLLLLLrrz)rkrr&rlDIRITTI_PARQUET_PATHrDIRITTI_ENRICH_PARQUET_PATH)r/ d_clausesd_params d_where_sqld_posix enrich_posixraw_colsselect_cols_sqld_fromrrrrrrs @@r_build_diritti_joinrEs(' Ir""NIx9BI47<< 22444rK"++--G.7799L;::I&8KBBBB>BBBHii       O "1  $   ".       F{{;776!! W $ $ $->LL;  B Bv B B B  99LL'(:KLLL L LD T8 ##rc . t|dgtd\}}|rdd|nd}t}t }ddh d  fd tD}d |d |d |d|d }|dd}|dkrd} n|dkrd} n|rdnd} | d|d} d d|dD} | | |fS)uJOIN su Gemma: a differenza degli altri domini, Gemma non ha "prodotto"/"edizione" propri — solo un riferimento IMDb (A_COD_IMDB). Su richiesta esplicita di Mauro il join non passa per A_CODICE_PRODOTTO (presente solo sul 9,5% delle righe) ma per IMDb: A_COD_IMDB -> imdb.riferimento_imdb -> imdb.codice = prodotti.prodotto. Il JOIN verso imdb dentro la subquery e' sempre INNER: una riga Gemma senza un codice IMDb valido/risolvibile non ha comunque modo di agganciarsi ad Anagrafica. ATTENZIONE fan-out: imdb.riferimento_imdb NON e' univoco (uno stesso id IMDb puo' corrispondere a piu' "codice" interni, fino a 41 osservati) — il join a catena puo' quindi restituire piu' righe di quante ce ne sarebbero con un match diretto 1:1. Accettato come caratteristica nota del dato (stesso principio gia' usato per il fan-out di Emesso/Diritti), non filtrato/deduplicato in questo primo giro. "a_data"/"a_deadline" sono stringhe in formato italiano GG/MM/AAAA nel parquet sorgente (non un tipo DATE nativo) — convertite a ISO qui via strptime, per usare lo stesso tipo "date" del resto del sistema. rxNrrrrrrrc3K|]>}|vrd|d|dnd|d|dV?dSzCAST(CAST(strptime(g."z(", '%d/%m/%Y') AS DATE) AS VARCHAR) AS "rNzg."z" AS "Nupperrs rrz$_build_gemma_join..s    >> [ZZVWZZZZ (17799 ( (A ( ( (      rz,( SELECT im."codice" AS "prodotto", z FROM read_parquet('z&') g INNER JOIN read_parquet('z8') im ON g."A_COD_IMDB" = im."riferimento_imdb" rrrrrrrrOz% gem ON a."prodotto" = gem."prodotto"c3(K|] }d|d|dVdS)zgem."z " AS "gemma_rNNrr|s rrz$_build_gemma_join..s6JJQ0Q00A000JJJJJJrrz)rkrr*rlGEMMA_PARQUET_PATHrIMDB_PARQUET_PATH) r0 g_clausesg_params g_where_sqlg_posix imdb_posixrg_fromrrrrrs @r_build_gemma_joinrs(' )R  ,DIx9BI47<< 22444rK ))++G"++--J<(Iii        O  +:  #  #-       Fyyf556!! W $ $ $->LL; KKfKKKH 99JJ%/JJJ J JD T8 ##rc t}t}t}d|d|d|d|d S)uFROM per Anagrafica, con i tre campi derivati (imdb_codice/regista/ attori) gia' agganciati — stessa logica di v_custom_anagr in Linker (PYTHON/MyICR_Suite/app/modules/linker/src/database/parquet_db.py), riletta 1:1 qui invece di reinventarla. Nessuna deduplicazione per "prodotto" (a differenza di v_custom_anagr, che tiene una sola edizione): PowerBricks espone il grano prodotto+edizione intero, i tre campi derivati sono comunque calcolati per "prodotto" quindi si ripetono identici su tutte le edizioni dello stesso prodotto — nessun fan-out, "codice" di imdb.parquet e' univoco (verificato: 110.773 righe = 110.773), "regista"/"attori" sono gia' aggregati a 1 riga per prodotto dalle subquery sotto. zh( SELECT p.*, i.riferimento_imdb AS imdb_codice, r.regista, c.attori FROM read_parquet('z}') p LEFT JOIN ( SELECT codice, MIN(riferimento_imdb) AS riferimento_imdb FROM read_parquet('z') GROUP BY codice ) i ON i.codice = p.prodotto LEFT JOIN ( SELECT prodotto, TRIM(COALESCE(nome, '') || ' ' || COALESCE(cognome, '')) AS regista FROM read_parquet('al') WHERE ruolo = 'FRE' QUALIFY ROW_NUMBER() OVER (PARTITION BY prodotto ORDER BY progr_cast) = 1 ) r ON r.prodotto = p.prodotto LEFT JOIN ( SELECT prodotto, STRING_AGG(TRIM(COALESCE(nome, '') || ' ' || COALESCE(cognome, '')), ', ' ORDER BY progr_cast) AS attori FROM read_parquet('z') WHERE ruolo = 'C001' AND progr_cast <= 3 GROUP BY prodotto ) c ON c.prodotto = p.prodotto )) PARQUET_PATHrrCAST_PARQUET_PATH) prod_posixr cast_posixs r_anagrafica_base_sqlrs&&((J"++--J"++--J &  !+   !+  "!+#    rc t|td\}}|rdd|nd} dd|D} d} g} |r't|\} }}| d| z } | |z } | d|} |r't |\}}}| d|z } | |z } | d|} |r't |\}}}| d|z } | |z } | d|} |r't |\}}}| d|z } | |z } | d|} d | d td | d | d |d }tj d}| || |z }d|j D}||fS)Narrrrrc3"K|] }d|dV dS)za."rNNrrcs rrz!_execute_query..s*>>1J!JJJ>>>>>>rrO SELECT  FROM z a  LIMIT  :memory:cg|] }|d Srrrs rrz"_execute_query.. ---qt---r) rkrrlrrrrrduckdbconnectexecutefetchall description)rxrryr-r.r/r0rsanagrafica_params where_sql select_colsr join_paramsemesso_join_sql emesso_colsr bo_join_sqlbo_colsr d_join_sqld_colsr g_join_sqlg_colsrsqlconrrs r_execute_queryr sH!-gv3!O!O!OG 4;C0g..000I))>> >>>>>KHK 66H6P6P3m))))}$ $55 55 2*? *J*J' Wi% %%%y $1111 1':7'C'C$ FH$ $$$x $0000  1'8'?'?$ FH$ $$$x $0000    "$$              C . $ $C ;;sK*;; < < E E G GD--S_---G D=rc|dkrdtdS|dkrDddtD}d|dtd S|d krvhd d d hfdt D}dfd|D}d|dt dtdS|dkrJddhdfdtD}d|dtdStd|)aFROM per la consultazione di un singolo dominio satellite SENZA passare da Anagrafica ("consultazione come tabella singola", Mauro, 06/08/2026: per una verifica mirata su un dominio non serve sempre comporre con Anagrafica). Ogni dominio riusa lo stesso cast dei campi data della modalita' unita a Anagrafica (necessario indipendentemente dal join, e' la serializzazione JSON che lo richiede), ma **senza** la logica che esiste solo in funzione del legame con Anagrafica: niente aggregazione prima/ultima per Emesso (concetto legato al confronto con piu' emissioni dello stesso prodotto/edizione, qui non c'e' un'edizione di riferimento), niente risoluzione IMDb per Gemma (serviva solo a calcolare "prodotto" per il join, qui gemma.parquet si legge cosi' com'e'). diritti_enrich resta agganciata (e' "trasparente", parte della stessa Tabella Diritti indipendentemente dal contesto). r-zread_parquet('z')r.rc3@K|]}|dkr d|d|dnd|dVdS)rmzCAST("rrNNrr|s rrz'_standalone_base_sql..-sa  34~2E2E .Q . .! . . . .8q888      rz(SELECT z FROM read_parquet('z'))r/rrrcg|]}|v| Srrrs rrz(_standalone_base_sql..5s#FFF!+1E1EA1E1E1Erc3>K|]}|vr d|d|dnd|dVdSrrrs rrz'_standalone_base_sql..6sa  67)^^ 1 1 1Q 1 1 1 1PQ      rz( SELECT z, en."fornitore_cluster" AS "fornitore_cluster", CAST(en."ESCLUSIVO_TEM" AS VARCHAR) AS "esclusivo_tem" FROM read_parquet('z*') dr LEFT JOIN read_parquet('zD') en ON dr."id_diritto" = en."id_diritto" )r0rrc3K|]>}|vrd|d|dnd|d|dV?dSrrrs rrz'_standalone_base_sql..Ds  I~~ _QWWYY ^ ^Z[ ^ ^ ^ ^,qwwyy,,,,,      rz') g).dominio non valido per consultazione singola: ) rrrlr"rr&rrr*rr)r7cols_sqlrrrs @@r_standalone_base_sqlrsC 3 < < > >BBBB 99  %     _(^^8N8W8W8Y8Y^^^^ >>> *O< FFFF~FFF99            !5 = = ? ?   &A%I%I%K%K     |, 99    "       ](\\8J8S8S8U8U\\\\ NfNN O OOrc|dpi}|d}|tvrtd|t||d}|t}fd|D}|rtd|d||std|d g}t t |d d |}||||fS) N standaloner7rrzcg|]}|v| Srr)rr}rs rrz*_parse_standalone_body..Xs#@@@Q1K+?+?q+?+?+?rzcampi non validi per rLr~rxryrM)rSTANDALONE_FIELDSrrrr!) rrrr7rrrxryrs @r_parse_standalone_bodyrNs,''-2J ^^H % %F &&&R&RRSSS#F+KNN8,,M[)) @@@@-@@@GFDDD7DDEEE B@AAAnnY++G DHHWc**++Y 7 7E 7M5 00rc t|}t||d\}}|rdd|nd}dd|D}t|} d|d| d |d |d } t jd } | | |} d | jD} | | fS)Nrrrrrc3"K|] }d|dV dS)rNNrrs rrz,_execute_standalone_query..gs*<<HHHH<<<<<.rrr) rrkrlrrrrrr)r7rxrryrrsrmrrbase_sqlrr rrs r_execute_standalone_queryrcs#F+K"7KTJJJOGV4;C0g..000I))<rBrFrHrIrarnrkrrrrrrr rrrrr!r*runrrrrAs  ###### >>>>>>>>>>>> DNN#*18!+,.78 00 "%55%(;;#&77 +-EE!O3!>1 >1 4>>))++29@:MPUU ) ) ) () x )   )  h ) X) ) U) ) )  e)  h)  8) 5)  !) "#) $" Q) ) ) b $ 6 *     "        " "  ( 8H G    W G F Fx  E!"%#$ "3B#        $: x: H:: f : h : 8 : h:: h::(:(:x:&:: h!:"H#::$ H%:& H':( H):* X+:, H-:. h/:0 X1:2 X3:4 X5:6 h7:8 X9:: X;:< X=:> X?:@ XA:B XC:D XE:::F XG:H XI:JxK:L XM:N HO:P HQ:R HS:T XU:V HW:X hY:Z X[:\ X]:^ X_:` ha:b Xc:d Xe:f Xg::h     s::: z       " %j $G $ > > > eHM2FFF+, &' ... +,,;;-,;   ! tH~~--//6=@WW QQQ  !!! 777 ::: !!@@"!@ << < 888!  %$&& """!  %$&& """/</</