K i$3dZddlZddlZddlZddlZddlZddlmZddlm Z  ddl m Z ddl m Z ddl m Z  ddlmZdd lmZdd lmZdd lmZej*d Zd ZGddeZeddZGddeZdZGddeZGddeeZGddeZ Gdde eZ! ddl"m#Z#Gdde e#Z$ dd l%m&Z&Gd!d"ee&Z'Gd#d$eZ(Gd%d&e(eZ) dd'l*m+Z+Gd(d)e(e+Z, dd*l*m-Z-Gd+d,e(e-Z.y#e$r dxZ xZ Z YwxYw#e$rYwxYw#e$rdZ$YvwxYw#e$rdZ'YpwxYw#e$rdZ,YSwxYw#e$rdZ.YywxYw)-aG Lightweight connection pooling for peewee. In a multi-threaded application, up to `max_connections` will be opened. Each thread (or, if using gevent, greenlet) will have it's own connection. In a single-threaded application, only one connection will be created. It will be continually recycled until either it exceeds the stale timeout or is closed explicitly (using `.manual_close()`). By default, all your application needs to do is ensure that connections are closed when you are finished with them, and they will be returned to the pool. For web applications, this typically means that at the beginning of a request, you will open a connection, and when you return a response, you will close the connection. Simple Postgres pool example code: # Use the special postgresql extensions. from playhouse.pool import PooledPostgresqlExtDatabase db = PooledPostgresqlExtDatabase( 'my_app', max_connections=32, stale_timeout=300, # 5 minutes. user='postgres') class BaseModel(Model): class Meta: database = db That's it! N) namedtuple)chain)TRANSACTION_STATUS_IDLE)TRANSACTION_STATUS_INERROR)TRANSACTION_STATUS_UNKNOWN)TransactionStatus) MySQLDatabase)PostgresqlDatabase)SqliteDatabasez peewee.poolcL|!t|ttfs t|S|SN) isinstanceintfloat)vals T/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/playhouse/pool.pymake_intr>s" z#U|<3x Jc eZdZy)MaxConnectionsExceededN__name__ __module__ __qualname__rrrrDsrrPoolConnection) timestamp connection checked_outceZdZdZy) _sentinelcyNTr)selfothers r__lt__z_sentinel.__lt__KsrN)rrrr&rrrr!r!Jsrr!cBtjfd}|S)Nc`|j5|g|i|cdddS#1swYyxYwr ) _pool_lock)r$argskwargsfns rinnerzlocked..innerPs1 __ -d,T,V, - - -s $-) functoolswraps)r,r-s` rlockedr0Os%__R-- LrceZdZ d fd Z dfd Zdfd ZefdZdZdZ dZ edfd Z ed Z ed Z edd Zed ZxZS)PooledDatabasec 0t||_t||_t||_|jdk(rt d|_t j |_g|_i|_ t|_ tt|:|fi|yNrinf)r_max_connections_stale_timeout _wait_timeoutr threadingRLockr) _connections_in_useidconn_keysuperr2__init__)r$databasemax_connections stale_timeouttimeoutr+ __class__s rr@zPooledDatabase.__init__Xs ( 9&}5%g.    "!&uD #//+    nd,X@@rc tt| |fi||t||_|t||_|1t||_|j dk(rtd|_yyyr4)r?r2initrr6r7r8r)r$rArBrCrDconnect_kwargsrEs rrGzPooledDatabase.initrst nd(D^D  &$,_$=D !  $"*="9D   !)'!2D !!Q&%*5\"' rcn|jstt||St j|jz}|t jkDr tt||}|St d#t $rt j dYnwxYw|t jkDr]H)Ng?z:Max connections exceeded, timed out attempting to connect.)r8r?r2connecttimersleep)r$ reuse_if_openexpiresretrEs rrJzPooledDatabase.connect~s!!6}E E))+ 2 22 # ND9-H $&>? ? *  3  #sA::BBc  tj|j\}}}|}|j|}|j |rt j d|dx}}nK|jr>|j|r-t j d||j|ddx}}nn||jr-t|j|jk\r tdtt |G}t%j$}|j|}t j d|t'||t%j$|j<|S#t$rdx}}t j dYwxYw)NTzConnection %s was closed.z!Connection %s was stale, closing.z No connection available in pool.zExceeded maximum connections.zCreated new connection %s.)heapqheappopr;r> _is_closedloggerdebugr7 _is_stale_close IndexErrorr6lenr<rr?r2_connectrKr)r$ts_c_connconnkeyrEs rrZzPooledDatabase._connects^  % d.?.? @ AvmmD) ??4( LL!)>>,-LMM79DB--%C LL5s ;*2tTYY[A S E   T ?@ s6E(("F  F cJtj|z |jkDSr )rKr7)r$rs rrVzPooledDatabase._is_stales  i'4+>+>>>rcy)NFrr$r^s rrSzPooledDatabase._is_closedsrcyr#rrbs r _can_reusezPooledDatabase._can_reusesrc0|j|}|rtt||y||jvr|jj |}|j rE|j|jr*tjd|tt||y|j|rLtjd|tj|j|jt|fytjd|yy)NzClosing stale connection %s.zReturning %s to pool.z Closed %s.)r>r?r2rWr<popr7rVrrTrUrdrQheappushr;r!)r$r^ close_connr_ pool_connrEs rrWzPooledDatabase._closesmmD!  .$ .t 4 DLL  ((-I""t~~i6I6I'J ;SAnd248& 4c:t00 ) 3 3Y[$GI \3/!rc|jry|j}|jj|j |d|j |j |dy)zS Close the underlying connection without returning it to the pool. FNTrh) is_closedrr<rfr>closerWrbs r manual_closezPooledDatabase.manual_closesW >>   t,d3  DT *rcb|jD]\}}}|j|dg|_yNTrk)r;rW)r$r\r^s r close_idlezPooledDatabase.close_idles7++ /JAq$ KKK . /rci}tj|z }d}|jjD]<\}}|j|kr#|j |j d|dz }8|||<>||_|S)NrTrk)rKr<itemsrrWr)r$agein_usecutoffnr_ris r close_stalezPooledDatabase.close_staless" "ll002 (NC$$v- I00T BQ's  (  rc|j|jD]\}}}|j|d|jj D]}|j|j d!g|_i|_yrp)rmr;rWr<valuesr)r$r\r^ris r close_allzPooledDatabase.close_allsy ++ /JAq$ KKK . /,,. ?I KK ,,K > ? r)NN)NNNF)iX)rrrr@rGrJr0rZrVrSrdrWrnrqryr| __classcell__)rEs@rr2r2WsCGA4BF 2 ? ) )V?  0 0  + +$           rr2ceZdZdZy)PooledMySQLDatabasec`|jddk(rd}nd} |j|y#YyxYw)Nrrr~FT)server_versionping)r$r^r*s rrSzPooledMySQLDatabase._is_closedsA   q !Q &DD  DIIt  s)-NrrrrSrrrrr s rrceZdZdZdZy)_PooledPostgresqlDatabasec|jry|j}|tk(ry|tk7r|j yNTF)closedget_transaction_statusrrrollbackr$r^ txn_statuss rrSz$_PooledPostgresqlDatabase._is_closeds; ;;002 3 3 2 2 MMOrc|j}|tk(ry|tk(r|jy|tk7r|j yNFT)rrrresetrrrs rrdz$_PooledPostgresqlDatabase._can_reuse'sL002  3 3 5 5 JJL2 2 MMOrNrrrrSrdrrrrrs   rrc eZdZy)PooledPostgresqlDatabaseNrrrrrr4rr)PostgresqlExtDatabasec eZdZy)PooledPostgresqlExtDatabaseNrrrrrr: rr)Psycopg3DatabaseceZdZdZdZy)PooledPsycopg3Databasec|jry|jj}|tjk(ry|tj k7r|j yr)rpgconntransaction_statusrUNKNOWNIDLErrs rrSz!PooledPsycopg3Database._is_closedDsH{{77J.6660555 rc|jj}|tjk(ry|tjk(r|j y|tj k7r|jyr)rrrrINERRORrrrrs rrdz!PooledPsycopg3Database._can_reuseOs_77J.6660888 0555 rNrrrrrrCs   rrceZdZdZy)_PooledSqliteDatabasec, |jy#YyxYwr) total_changesrbs rrSz _PooledSqliteDatabase._is_closed`s     s Nrrrrrr_srrc eZdZy)PooledSqliteDatabaseNrrrrrrhrrr)SqliteExtDatabasec eZdZy)PooledSqliteExtDatabaseNrrrrrrnrrr)CSqliteExtDatabasec eZdZy)PooledCSqliteExtDatabaseNrrrrrrvrrr)/__doc__r.rQloggingr9rK collectionsr itertoolsrpsycopg2.extensionsrrr ImportError psycopg.pqrpeeweer r r getLoggerrTr ValueErrorrrobjectr!r0r2rrrplayhouse.postgres_extrrplayhouse.psycopg3_extrrrrplayhouse.sqlite_extrrrrrrrrs B  ".;>>  ,!%!   = ) /Z.,/>? sVsl .- 2 8:L '< &?AV "71A8N 0. #6 "79J $7 #8:L Q .*... & &.   P'"&'>"!"*#"#$#$sjDD)5D4E2EE D&%D&)D10D14D>=D>E  E EEE%$E%