reydb 1.3.5__py3-none-any.whl → 1.3.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
reydb/rconn.py CHANGED
@@ -223,7 +223,6 @@ class DatabaseConnectionAsync(DatabaseConnectionSuper['rengine.DatabaseEngineAsy
223
223
 
224
224
  # Close.
225
225
  await self.close()
226
- await self.engine.dispose()
227
226
 
228
227
 
229
228
  async def get_conn(self) -> AsyncConnection:
reydb/rdb.py CHANGED
@@ -10,8 +10,9 @@
10
10
 
11
11
 
12
12
  from typing import Any, TypeVar, Generic, overload
13
- from collections.abc import Sequence
13
+ from collections.abc import Iterable, Sequence
14
14
  from reykit.rbase import Null, throw
15
+ from reykit.rtask import ThreadPool, async_gather
15
16
 
16
17
  from .rbase import DatabaseBase
17
18
  from .rengine import DatabaseEngine, DatabaseEngineAsync
@@ -52,8 +53,8 @@ class DatabaseSuper(DatabaseBase, Generic[DatabaseEngineT]):
52
53
  username: str,
53
54
  password: str,
54
55
  database: str,
55
- pool_size: int = 5,
56
- max_overflow: int = 10,
56
+ max_pool: int = 15,
57
+ max_keep: int = 5,
57
58
  pool_timeout: float = 30.0,
58
59
  pool_recycle: int | None = 3600,
59
60
  echo: bool = False,
@@ -79,8 +80,8 @@ class DatabaseSuper(DatabaseBase, Generic[DatabaseEngineT]):
79
80
  username : Remote server database username.
80
81
  password : Remote server database password.
81
82
  database : Remote server database name.
82
- pool_size : Number of connections `keep open`.
83
- max_overflow : Number of connections `allowed overflow`.
83
+ max_pool : Maximum number of connections in the pool.
84
+ max_keep : Maximum number of connections keeped.
84
85
  pool_timeout : Number of seconds `wait create` connection.
85
86
  pool_recycle : Number of seconds `recycle` connection.
86
87
  - `None | Literal[-1]`: No recycle.
@@ -136,28 +137,118 @@ class DatabaseSuper(DatabaseBase, Generic[DatabaseEngineT]):
136
137
  __getitem__ = __getattr__
137
138
 
138
139
 
139
- def __contains__(self, database: str) -> bool:
140
+ def __contains__(self, name: str) -> bool:
140
141
  """
141
142
  Whether the exist this database engine.
142
143
 
143
144
  Parameters
144
145
  ----------
145
- database : Database name.
146
+ name : Database engine name.
146
147
  """
147
148
 
148
149
  # Judge.
149
- result = database in self.__engine_dict
150
+ result = name in self.__engine_dict
150
151
 
151
152
  return result
152
153
 
153
154
 
155
+ def __iter__(self) -> Iterable[str]:
156
+ """
157
+ Iterable of database engine names.
158
+ """
159
+
160
+ # Generate.
161
+ names = iter(self.__engine_dict)
162
+
163
+ return names
164
+
165
+
154
166
  class Database(DatabaseSuper[DatabaseEngine]):
155
167
  """
156
168
  Database type.
157
169
  """
158
170
 
159
171
 
172
+ def warm_all(self, num: int | None = None) -> None:
173
+ """
174
+ Pre create connection to warm all pool.
175
+
176
+ Parameters
177
+ ----------
178
+ num : Create number.
179
+ - `None`: Use `self.max_keep` value.
180
+ """
181
+
182
+ # Parameter.
183
+ engines = set(
184
+ [
185
+ self[name]
186
+ for name in self
187
+ ]
188
+ )
189
+
190
+ # Warm.
191
+
192
+ ## Create.
193
+ func = lambda engine: engine.connect().close()
194
+ pool = ThreadPool(func, _max_workers=num)
195
+ for engine in engines:
196
+ engine_num = num or engine.max_keep
197
+ for _ in range(engine_num):
198
+ pool.one(engine.engine)
199
+
200
+ ## Wait.
201
+ pool.join()
202
+
203
+
160
204
  class DatabaseAsync(DatabaseSuper[DatabaseEngineAsync]):
161
205
  """
162
206
  Asynchronous database type.
163
207
  """
208
+
209
+
210
+ async def warm_all(self, num: int | None = None) -> None:
211
+ """
212
+ Asynchronous pre create connection to warm all pool.
213
+
214
+ Parameters
215
+ ----------
216
+ num : Create number.
217
+ - `None`: Use `self.max_keep` value.
218
+ """
219
+
220
+ # Parameter.
221
+ engines = set(
222
+ [
223
+ self[name]
224
+ for name in self
225
+ ]
226
+ )
227
+
228
+ # Warm.
229
+ coroutines = [
230
+ engine.warm(num)
231
+ for engine in engines
232
+ ]
233
+ await async_gather(*coroutines)
234
+
235
+
236
+ async def dispose_all(self) -> None:
237
+ """
238
+ Dispose asynchronous connections of all database.
239
+ """
240
+
241
+ # Parameter.
242
+ engines = set(
243
+ [
244
+ self[name]
245
+ for name in self
246
+ ]
247
+ )
248
+
249
+ # Dispose.
250
+ coroutines = [
251
+ engine.dispose()
252
+ for engine in engines
253
+ ]
254
+ await async_gather(*coroutines)
reydb/rengine.py CHANGED
@@ -9,11 +9,13 @@
9
9
  """
10
10
 
11
11
 
12
- from typing import TypeVar, Generic, overload
12
+ from typing import TypeVar, Generic
13
13
  from urllib.parse import quote as urllib_quote
14
14
  from pymysql.constants.CLIENT import MULTI_STATEMENTS
15
15
  from sqlalchemy import Engine, create_engine as sqlalchemy_create_engine
16
16
  from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine as sqlalchemy_create_async_engine
17
+ from reykit.rbase import throw
18
+ from reykit.rtask import ThreadPool, async_gather
17
19
  from reykit.rtext import join_data_text
18
20
 
19
21
  from . import rbase, rbuild, rconfig, rconn, rerror, rexec, rinfo, rorm
@@ -86,8 +88,8 @@ class DatabaseEngineSuper(
86
88
  username: str,
87
89
  password: str,
88
90
  database: str,
89
- pool_size: int = 5,
90
- max_overflow: int = 10,
91
+ max_pool: int = 15,
92
+ max_keep: int = 5,
91
93
  pool_timeout: float = 30.0,
92
94
  pool_recycle: int | None = 3600,
93
95
  echo: bool = False,
@@ -103,10 +105,10 @@ class DatabaseEngineSuper(
103
105
  username : Remote server database username.
104
106
  password : Remote server database password.
105
107
  database : Remote server database name.
106
- pool_size : Number of connections `keep open`.
107
- max_overflow : Number of connections `allowed overflow`.
108
- pool_timeout : Number of seconds `wait create` connection.
109
- pool_recycle : Number of seconds `recycle` connection.
108
+ max_pool : Maximum number of connections in the pool.
109
+ max_keep : Maximum number of connections keeped.
110
+ pool_timeout : Number of seconds wait create connection.
111
+ pool_recycle : Number of seconds recycle connection.
110
112
  - `None | Literal[-1]`: No recycle.
111
113
  - `int`: Use this value.
112
114
  echo : Whether report SQL execute information, not include ORM execute.
@@ -114,6 +116,8 @@ class DatabaseEngineSuper(
114
116
  """
115
117
 
116
118
  # Parameter.
119
+ if max_keep > max_pool:
120
+ throw(ValueError, max_keep, max_pool)
117
121
  if type(port) == str:
118
122
  port = int(port)
119
123
 
@@ -123,8 +127,8 @@ class DatabaseEngineSuper(
123
127
  self.host = host
124
128
  self.port: int | None = port
125
129
  self.database = database
126
- self.pool_size = pool_size
127
- self.max_overflow = max_overflow
130
+ self.max_pool = max_pool
131
+ self.max_keep = max_keep
128
132
  self.pool_timeout = pool_timeout
129
133
  if pool_recycle is None:
130
134
  self.pool_recycle = -1
@@ -238,10 +242,11 @@ class DatabaseEngineSuper(
238
242
  """
239
243
 
240
244
  # Parameter.
245
+ max_overflow = self.max_pool - self.max_keep
241
246
  engine_params = {
242
247
  'url': self.url,
243
- 'pool_size': self.pool_size,
244
- 'max_overflow': self.max_overflow,
248
+ 'pool_size': self.max_keep,
249
+ 'max_overflow': max_overflow,
245
250
  'pool_timeout': self.pool_timeout,
246
251
  'pool_recycle': self.pool_recycle,
247
252
  'connect_args': {'client_flag': MULTI_STATEMENTS}
@@ -270,10 +275,10 @@ class DatabaseEngineSuper(
270
275
  # Count.
271
276
  _overflow: int = self.engine.pool._overflow
272
277
  if _overflow < 0:
273
- keep_n = self.pool_size + _overflow
278
+ keep_n = self.max_keep + _overflow
274
279
  overflow_n = 0
275
280
  else:
276
- keep_n = self.pool_size
281
+ keep_n = self.max_keep
277
282
  overflow_n = _overflow
278
283
 
279
284
  return keep_n, overflow_n
@@ -532,8 +537,8 @@ class DatabaseEngine(
532
537
  self.username,
533
538
  self.password,
534
539
  self.database,
535
- self.pool_size,
536
- self.max_overflow,
540
+ self.max_pool,
541
+ self.max_keep,
537
542
  self.pool_timeout,
538
543
  self.pool_recycle,
539
544
  self.echo,
@@ -543,6 +548,31 @@ class DatabaseEngine(
543
548
  return db
544
549
 
545
550
 
551
+ def warm(self, num: int | None = None) -> None:
552
+ """
553
+ Pre create connection to warm pool.
554
+
555
+ Parameters
556
+ ----------
557
+ num : Create number.
558
+ - `None`: Use `self.max_keep` value.
559
+ """
560
+
561
+ # Parameter.
562
+ if num is None:
563
+ num = self.max_keep
564
+
565
+ # Warm.
566
+
567
+ ## Create.
568
+ func = lambda: self.engine.connect().close()
569
+ pool = ThreadPool(func, _max_workers=num)
570
+ pool * 5
571
+
572
+ ## Wait.
573
+ pool.join()
574
+
575
+
546
576
  class DatabaseEngineAsync(
547
577
  DatabaseEngineSuper[
548
578
  AsyncEngine,
@@ -576,8 +606,8 @@ class DatabaseEngineAsync(
576
606
  self.username,
577
607
  self.password,
578
608
  self.database,
579
- self.pool_size,
580
- self.max_overflow,
609
+ self.max_pool,
610
+ self.max_keep,
581
611
  self.pool_timeout,
582
612
  self.pool_recycle,
583
613
  self.echo,
@@ -587,6 +617,37 @@ class DatabaseEngineAsync(
587
617
  return db
588
618
 
589
619
 
620
+ async def warm(self, num: int | None = None) -> None:
621
+ """
622
+ Asynchronous pre create connection to warm pool.
623
+
624
+ Parameters
625
+ ----------
626
+ num : Create number.
627
+ - `None`: Use `self.max_keep` value.
628
+ """
629
+
630
+ # Parameter.
631
+ if num is None:
632
+ num = self.max_keep
633
+
634
+ # Warm.
635
+
636
+ ## Create.
637
+ coroutines = [
638
+ self.engine.connect()
639
+ for _ in range(num)
640
+ ]
641
+ conns = await async_gather(*coroutines)
642
+
643
+ ## Close.
644
+ coroutines = [
645
+ conn.close()
646
+ for conn in conns
647
+ ]
648
+ await async_gather(*coroutines)
649
+
650
+
590
651
  async def dispose(self) -> None:
591
652
  """
592
653
  Dispose asynchronous connections.
reydb/rexec.py CHANGED
@@ -1227,7 +1227,6 @@ class DatabaseExecuteAsync(DatabaseExecuteSuper['rconn.DatabaseConnectionAsync']
1227
1227
  if self.conn.autocommit:
1228
1228
  await self.conn.commit()
1229
1229
  await self.conn.close()
1230
- await self.conn.engine.dispose()
1231
1230
 
1232
1231
  return result
1233
1232
 
reydb/rorm.py CHANGED
@@ -1151,7 +1151,6 @@ class DatabaseORMSessionAsync(
1151
1151
 
1152
1152
  # Close.
1153
1153
  await self.close()
1154
- await self.orm.engine.dispose()
1155
1154
 
1156
1155
 
1157
1156
  def get_sess(self) -> AsyncSession:
@@ -1262,7 +1261,6 @@ class DatabaseORMSessionAsync(
1262
1261
  if self.autocommit:
1263
1262
  await self.commit()
1264
1263
  await self.close()
1265
- await self.orm.engine.dispose()
1266
1264
 
1267
1265
  return result
1268
1266
 
@@ -1604,7 +1602,6 @@ class DatabaseORMStatementAsync(DatabaseORMStatementSuper[DatabaseORMSessionAsyn
1604
1602
 
1605
1603
  await self.sess.commit()
1606
1604
  await self.sess.close()
1607
- await self.sess.orm.engine.dispose()
1608
1605
 
1609
1606
  return result
1610
1607
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reydb
3
- Version: 1.3.5
3
+ Version: 1.3.6
4
4
  Summary: Database method set.
5
5
  Project-URL: homepage, https://github.com/reyxbo/reydb/
6
6
  Author-email: Rey <reyxbo@163.com>
@@ -0,0 +1,16 @@
1
+ reydb/__init__.py,sha256=BnJsTzcwqeQ8-5Boqsehgcpc1eSDkv41v0kdb10gAgM,643
2
+ reydb/rall.py,sha256=5GI0yuwF72XypNZ1DYIxKizo2Z5pR88Uv0nUpHKYhCk,379
3
+ reydb/rbase.py,sha256=S3ip2PxvLn2Spgv5G_xd7xgC-U4wjEoAZ7Up25ZQvLk,8223
4
+ reydb/rbuild.py,sha256=6ZkU3LGkIk04KTPtd8fgTC4pX93p1tvbOhZWWEi-v5A,40846
5
+ reydb/rconfig.py,sha256=DFGTyoixqlSMGeWyd1os9K7YxnyY3RfgvPqQzZQlMQM,18161
6
+ reydb/rconn.py,sha256=ujyTAqR7FLr758EHDr04e0MTHDGDQEF_-YkfkYc8XRI,6986
7
+ reydb/rdb.py,sha256=IhZLyXWZ5tiTWe2oq-nEkzTJW2ClvgT2-37OK-eOTXU,6063
8
+ reydb/rengine.py,sha256=4tEIWxhtQ220_DZYb180hXhUwcxKGnPcv0yLaH1l0X4,17048
9
+ reydb/rerror.py,sha256=M7RPXwywLYl5Vew7jfXxUxVnBrM1b_T6V9Izt4B8zI0,14791
10
+ reydb/rexec.py,sha256=bVPT8kueKnK5HWLtYklE5Vgc4crL7QxBEE3S0MQgRB4,52647
11
+ reydb/rinfo.py,sha256=c5otyOikGMVnLFhPbtlgmnFBRR3NMP7xcmMW-LQdaQk,18314
12
+ reydb/rorm.py,sha256=74WHZ3wKa3y8bqHR9CcJO2JBc4Z8A8eTAmFae8RL0Hc,49862
13
+ reydb-1.3.6.dist-info/METADATA,sha256=kM7W1Wu13bUxQ11aAytu8QMl_FPmCQxE49iAZG304kk,1653
14
+ reydb-1.3.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
+ reydb-1.3.6.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
16
+ reydb-1.3.6.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- reydb/__init__.py,sha256=BnJsTzcwqeQ8-5Boqsehgcpc1eSDkv41v0kdb10gAgM,643
2
- reydb/rall.py,sha256=5GI0yuwF72XypNZ1DYIxKizo2Z5pR88Uv0nUpHKYhCk,379
3
- reydb/rbase.py,sha256=S3ip2PxvLn2Spgv5G_xd7xgC-U4wjEoAZ7Up25ZQvLk,8223
4
- reydb/rbuild.py,sha256=6ZkU3LGkIk04KTPtd8fgTC4pX93p1tvbOhZWWEi-v5A,40846
5
- reydb/rconfig.py,sha256=DFGTyoixqlSMGeWyd1os9K7YxnyY3RfgvPqQzZQlMQM,18161
6
- reydb/rconn.py,sha256=K_k6cJ94yrPIFaSZ06enpguTWVPhDu67LHan41C1bRA,7023
7
- reydb/rdb.py,sha256=LblF7igyr5y1lyrSRZIKcYI9M9rzWG-mdcJYWINlARw,4014
8
- reydb/rengine.py,sha256=qkpEsfHleia-bT7DBgERpSlZfszB5mLbRACtG-H2D-s,15640
9
- reydb/rerror.py,sha256=M7RPXwywLYl5Vew7jfXxUxVnBrM1b_T6V9Izt4B8zI0,14791
10
- reydb/rexec.py,sha256=Bbjqh0e3dE_NRnSfKfyfyyzAvXKdzXT5JLuzufHuH_s,52693
11
- reydb/rinfo.py,sha256=c5otyOikGMVnLFhPbtlgmnFBRR3NMP7xcmMW-LQdaQk,18314
12
- reydb/rorm.py,sha256=UHZVNHkQ31RyJ5Ia9wmJ8ammIz59KKYOKh9HX6VEHX4,50002
13
- reydb-1.3.5.dist-info/METADATA,sha256=mxZmvHnUjHkt1iyQSfuaah-57VMDfbkwEvN0TDBqKZ0,1653
14
- reydb-1.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
- reydb-1.3.5.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
16
- reydb-1.3.5.dist-info/RECORD,,
File without changes