+ 2iaRt0tRt^RIt^RIt^RIt^RIt^RIt]PPRR4t RRRRRRRRRRR RR R/t ]^kRR0t .R Ot ^t R R ltR RltR!RRlltRRltRRltRRlt]R8Xd ]!4R#R#)"u pg_trickle demo — continuous transaction generator. Inserts ~1 transaction per second with occasional "suspicious burst" patterns (rapid transactions from the same user at Crypto/Gambling merchants with escalating amounts) that drive HIGH-risk scores in the fraud detection DAG. N DATABASE_URLz*postgresql://demo:demo@postgres/fraud_demoRetail ElectronicsTravelGamblingCryptoFoodPharmacyc$V^8dQhR\/#)url)str)formats"B/Users/geir.gronmo/projects/pg-trickle2/demo/generator/generate.py __annotate__r'sNNNc8\^^=4F4p\P!V4pRVn\ RV R2RR7Vu# \R4h \P d5p\ RT RT 2RR7\ P!^4Rp?KRp?ii;i) z"Retry until the database is ready.Tz[GENERATOR] Connected (attempt )flushz$[GENERATOR] Waiting for DB (attempt z/60): Nz3Could not connect to the database after 60 attempts) rangepsycopg2connect autocommitprintOperationalErrortimesleep RuntimeError)r attemptconnexcs& rrr'sB< ##C(D"DO 3G9A>d KK   L MM ((  6wivcUK  JJqMM  s/AB%)BBcV^8dQhR\\\,\\\\3,,3,/#)r return)tuplelistintr )rs"rrr8s.5cDsCx,A!ABrctVP4;_uu_4pVPR4VP4Uu.uF q"^,NK ppVPR4VP4Uu.uFq"^,V^,3NK ppRRR4W43#uupiuupi +'giXX3#;i)z0Load user IDs and (merchant_id, category) pairs.z SELECT id FROM users ORDER BY idz.SELECT id, category FROM merchants ORDER BY idN)cursorexecutefetchall)r currowusers merchantss& r fetch_lookupsr/8s # 67#&<<>2>CQ>2 DE14@#!fc!f% @   3@  ) s($B$B%B$3B B$ B$$ B7 c<V^8dQhR\R\R\/#)r category multiplierr#)r float)rs"rrrBs!22C2U2U2rc \PVR4wr#\P!W#,R, 4p\P !VR4V,p\ \R\VR44^4#)z@Log-normal amount centred between the category's low/high range.g@g??gQ@)g4@gi@) CATEGORY_AMOUNTSgetmathlograndomlognormvariateroundmaxmin)r1r2lohimuraws&& r sample_amountrCBs\  ! !(M :FB 27c/ "B   D )J 6C S#c8,-q 11rc(V^8dQhR\RR/#)r merchant_idr#N)r&)rs"rrrJsCDrcVP4;_uu_4pVPRV34VP4pV'dV^,\9d V^,M \^,p\\P V4^,\ \4,,pVPRWQ34\ RVR RV 2RR7RRR4R# +'giR#;i) uURotate one merchant's risk tier to the next value (STANDARD→ELEVATED→HIGH→…).z:SELECT tier FROM merchant_risk_tier WHERE merchant_id = %szRUPDATE merchant_risk_tier SET tier = %s, updated_at = now() WHERE merchant_id = %sz[TIER] merchant >2u → TrN)r(r)fetchone TIER_ORDERindexlenr)r rEr+r,currentnew_tiers&& rrotate_merchant_tierrNJs # H N lln  #A* 4c!f*Q-G!:#3#3G#6z user=rGz merchant=z (z<14z) $z>9.2fz[GENERATOR] Insert error: )rrr/RISKY_CATEGORIESrrKr:choicerandintTIER_UPDATE_INTERVALrNrErrorrCuniformrSclose Exceptionrr)r r-r.midcatmerchant_by_idmall_ids risky_idscycle burst_userburst_remaining tier_merchantr!rPrEr1 escalationrQsleep_stxn_ids rmainrmjs] < D$T*E/89y83chyN9&'YttYG'(Ey!aD4D,D1yEPPI c%j\#i.1AB  E!JO    a EBJ!Ou-J$nnQ3O -j\:#$L2  ' '1 ,"MM'2M K$T9* "z'=$$mmI6 )6 Oc$9: &xJG1$"a'!%J ..t4!--.$mmG4 )6&x0 ..c2{FCF F2;ggb\:'+2n.I#-NO5>#  , 7c:'E@>> K7u=TJJ K@~~  .se4D A    <(D,T2 E7@Ay83chyANA%./YttY/G/(Ey!aD4D,D1yEPP G s II I % I 4 I%C-M9>KM9 KM9K$M9 LM9L.- M99M MM9.M99M>__main__cV^8dQh/^\9d,\\\\\3,3,;R&#)r r6)__conditional_annotations__dictr r$r3)rs"rrrs5($sE%,//0)r)g.@gr@)gT@gp@)gb@g@)g9@g@)gI@g@@)g @gV@)g(@gf@)STANDARDELEVATEDHIGH)r5)rp__doc__r8osr:rrenvironr7rr6rXrIr[rr/rCrNrSrm__name__r)rps@rrys zz~~@  ?? "? ? N?4j). N"2,!Tn zFr