reydb 1.1.52__py3-none-any.whl → 1.1.53__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/rfile.py CHANGED
@@ -359,7 +359,7 @@ class DatabaseFile(DatabaseBase):
359
359
  )
360
360
 
361
361
  # Get ID.
362
- file_id = conn.insert_id
362
+ file_id = conn.insert_id()
363
363
 
364
364
  # Commit.
365
365
  conn.commit()
reydb/rorm.py CHANGED
@@ -9,14 +9,18 @@
9
9
  """
10
10
 
11
11
 
12
- from typing import Self, Any, Type, TypeVar, Generic, Final
12
+ from typing import Self, Any, Type, TypeVar, Generic, Final, overload
13
+ from collections.abc import Callable
13
14
  from functools import wraps as functools_wraps
14
15
  from pydantic import ConfigDict, field_validator as pydantic_field_validator, model_validator as pydantic_model_validator
15
16
  from sqlalchemy.orm import SessionTransaction
17
+ from sqlalchemy.sql import sqltypes
18
+ from sqlalchemy.sql.sqltypes import TypeEngine
16
19
  from sqlalchemy.sql.dml import Insert, Update, Delete
17
- from sqlmodel import SQLModel, Session, Table, Field as sqlmodel_Field
20
+ from sqlmodel import SQLModel, Session, Table
21
+ from sqlmodel.main import SQLModelMetaclass, FieldInfo
18
22
  from sqlmodel.sql._expression_select_cls import SelectOfScalar as Select
19
- from reykit.rbase import CallableT, is_instance
23
+ from reykit.rbase import CallableT, Null, is_instance
20
24
 
21
25
  from .rbase import DatabaseBase
22
26
  from .rdb import Database
@@ -24,7 +28,9 @@ from .rdb import Database
24
28
 
25
29
  __all__ = (
26
30
  'DatabaseORMBase',
31
+ 'DatabaseORMModelMeta',
27
32
  'DatabaseORMModel',
33
+ 'DatabaseORMModelField',
28
34
  'DatabaseORM',
29
35
  'DatabaseORMSession',
30
36
  'DatabaseORMStatement',
@@ -35,21 +41,72 @@ __all__ = (
35
41
  )
36
42
 
37
43
 
44
+ ModelT = TypeVar('ModelT', bound='DatabaseORMModel')
45
+
46
+
38
47
  class DatabaseORMBase(DatabaseBase):
39
48
  """
40
49
  Database ORM base type.
41
50
  """
42
51
 
43
52
 
44
- class DatabaseORMModelField(DatabaseBase):
53
+ class DatabaseORMModelMeta(DatabaseORMBase, SQLModelMetaclass):
45
54
  """
46
- Database ORM model filed type.
55
+ Database ORM base meta type.
47
56
  """
48
57
 
49
58
 
50
- class DatabaseORMModel(DatabaseORMBase, SQLModel):
59
+ def __new__(
60
+ cls,
61
+ name: str,
62
+ bases: tuple[Type],
63
+ attrs: dict[str, Any],
64
+ **kwargs: Any
65
+ ) -> Type:
66
+ """
67
+ Create type.
68
+
69
+ Parameters
70
+ ----------
71
+ name : Type name.
72
+ bases : Type base types.
73
+ attrs : Type attributes and methods dictionary.
74
+ kwargs : Type other key arguments.
75
+ """
76
+
77
+ # Handle parameter.
78
+ if attrs['__module__'] == '__main__':
79
+ table_args = attrs.setdefault('__table_args__', {})
80
+ table_args['quote'] = True
81
+ if '__comment__' in attrs:
82
+ table_args['comment'] = attrs.pop('__comment__')
83
+
84
+ ## Field.
85
+ for __name__ in attrs['__annotations__']:
86
+ field = attrs.get(__name__)
87
+ if field is None:
88
+ field = attrs[__name__] = DatabaseORMModelField()
89
+ sa_column_kwargs: dict = field.sa_column_kwargs
90
+ sa_column_kwargs.setdefault('name', __name__)
91
+
92
+ # Base.
93
+ new_cls = super().__new__(cls, name, bases, attrs, **kwargs)
94
+
95
+ return new_cls
96
+
97
+
98
+ model_metaclass: SQLModelMetaclass = DatabaseORMModelMeta
99
+
100
+
101
+ class DatabaseORMModel(DatabaseORMBase, SQLModel, metaclass=model_metaclass):
51
102
  """
52
103
  Database ORM model type.
104
+
105
+ Examples
106
+ --------
107
+ >>> class Foo(DatabaseORMModel, table=True):
108
+ ... __comment__ = 'Table comment.'
109
+ ... ...
53
110
  """
54
111
 
55
112
 
@@ -110,54 +167,188 @@ class DatabaseORMModel(DatabaseORMBase, SQLModel):
110
167
 
111
168
 
112
169
  @classmethod
113
- def table(cls_or_self) -> Table:
170
+ def table(cls_or_self) -> Table | None:
114
171
  """
115
172
  Mapping `Table` instance.
116
173
 
117
174
  Returns
118
175
  -------
119
- Instance.
176
+ Instance or null.
120
177
  """
121
178
 
122
179
  # Get.
123
- table: Table = cls_or_self.__table__
180
+ table: Table | None = getattr(cls_or_self, '__table__', None)
124
181
 
125
182
  return table
126
183
 
127
184
 
128
185
  @classmethod
129
- def comment(cls_or_self) -> str | None:
186
+ def comment(cls_or_self, comment: str) -> None:
130
187
  """
131
- Table comment.
188
+ Set table comment.
132
189
 
133
- Returns
134
- -------
135
- Comment.
190
+ Parameters
191
+ ----------
192
+ comment : Comment.
136
193
  """
137
194
 
138
- # Get.
195
+ # Set.
139
196
  table = cls_or_self.table()
140
- comment = table.comment
197
+ table.comment = comment
141
198
 
142
- return comment
143
199
 
200
+ class DatabaseORMModelField(DatabaseBase, FieldInfo):
201
+ """
202
+ Database ORM model filed type.
144
203
 
145
- @classmethod
146
- def set_comment(cls_or_self, comment: str) -> None:
204
+ Examples
205
+ --------
206
+ >>> class Foo(DatabaseORMModel, table=True):
207
+ ... key: int = DatabaseORMModelField(key=True, commment='Field commment.')
208
+ """
209
+
210
+
211
+ @overload
212
+ def __init__(
213
+ self,
214
+ arg_default: Any | Callable[[], Any] | Null = Null,
215
+ *,
216
+ arg_name: str | None = None,
217
+ field_default: str | None = None,
218
+ filed_name: str | None = None,
219
+ field_type: TypeEngine | None = None,
220
+ key: bool = False,
221
+ key_auto: bool = False,
222
+ non_null: bool = False,
223
+ index_n: bool = False,
224
+ index_u: bool = False,
225
+ comment: str | None = None,
226
+ unique: bool = False,
227
+ re: str | None = None,
228
+ len_min: int | None = None,
229
+ len_max: int | None = None,
230
+ num_gt: float | None = None,
231
+ num_ge: float | None = None,
232
+ num_lt: float | None = None,
233
+ num_le: float | None = None,
234
+ num_multiple: float | None = None,
235
+ num_places: int | None = None,
236
+ num_places_dec: int | None = None,
237
+ **kwargs: Any
238
+ ) -> None: ...
239
+
240
+ def __init__(
241
+ self,
242
+ arg_default: Any | Callable[[], Any] | Null = Null,
243
+ **kwargs: Any
244
+ ) -> None:
147
245
  """
148
- Set table comment.
246
+ Build instance attributes.
149
247
 
150
248
  Parameters
151
249
  ----------
152
- comment : Comment.
250
+ arg_default : Call argument default value.
251
+ arg_name : Call argument name.
252
+ - `None`: Same as attribute name.
253
+ field_default : Database field defualt value.
254
+ filed_name : Database field name.
255
+ - `None`: Same as attribute name.
256
+ field_type : Database field type.
257
+ - `None`: Based type annotation automatic judgment.
258
+ key : Whether the field is primary key.
259
+ key_auto : Whether the field is automatic increment primary key.
260
+ non_null : Whether the field is non null constraint.
261
+ index_n : Whether the field add normal index.
262
+ index_u : Whether the field add unique index.
263
+ comment : Field commment.
264
+ unique : Require the sequence element if is all unique.
265
+ re : Require the partial string if is match regular expression.
266
+ len_min : Require the sequence or string minimum length.
267
+ len_max : Require the sequence or string maximum length.
268
+ num_gt : Require the number greater than this value. (i.e. `number > num_gt`)
269
+ num_lt : Require the number less than this value. (i.e. `number < num_lt`)
270
+ num_ge : Require the number greater than and equal to this value. (i.e. `number >= num_ge`)
271
+ num_le : Require the number less than and equal to this value. (i.e. `number <= num_le`)
272
+ num_multiple : Require the number to be multiple of this value. (i.e. `number % num_multiple == 0`)
273
+ num_places : Require the number digit places maximum length.
274
+ num_places_dec : Require the number decimal places maximum length.
275
+ **kwargs : Other key arguments.
153
276
  """
154
277
 
155
- # Set.
156
- table = cls_or_self.table()
157
- table.comment = comment
278
+ # Handle parameter.
279
+ kwargs = {
280
+ key: value
281
+ for key, value in kwargs.items()
282
+ if value not in (None, False)
283
+ }
284
+ kwargs.setdefault('sa_column_kwargs', {})
285
+ kwargs['sa_column_kwargs']['quote'] = True
286
+
287
+ ## Convert argument name.
288
+ mapping_keys = {
289
+ 'arg_name': 'alias',
290
+ 'key': 'primary_key',
291
+ 'index_n': 'index',
292
+ 'index_u': 'unique',
293
+ 're': 'pattern',
294
+ 'len_min': ('min_length', 'min_items'),
295
+ 'len_max': ('max_length', 'max_items'),
296
+ 'num_gt': 'gt',
297
+ 'num_ge': 'ge',
298
+ 'num_lt': 'lt',
299
+ 'num_le': 'le',
300
+ 'num_multiple': 'multiple_of',
301
+ 'num_places': 'max_digits',
302
+ 'num_places_dec': 'decimal_places'
303
+ }
304
+
305
+ for key_old, key_new in mapping_keys.items():
306
+ if type(key_new) != tuple:
307
+ key_new = (key_new,)
308
+ if key_old in kwargs:
309
+ value = kwargs.pop(key_old)
310
+ for key in key_new:
311
+ kwargs[key] = value
312
+
313
+ ## Argument default.
314
+ if (
315
+ arg_default != Null
316
+ and callable(arg_default)
317
+ ):
318
+ kwargs['default_factory'] = arg_default
319
+ else:
320
+ kwargs['default'] = arg_default
321
+
322
+ ## Field default.
323
+ if 'field_default' in kwargs:
324
+ kwargs['sa_column_kwargs']['server_default'] = kwargs.pop('field_default')
325
+
326
+ ## Field name.
327
+ if 'filed_name' in kwargs:
328
+ kwargs['sa_column_kwargs']['name'] = kwargs.pop('filed_name')
329
+
330
+ ## Field type.
331
+ if 'filed_name' in kwargs:
332
+ kwargs['sa_column_kwargs']['type_'] = kwargs.pop('filed_type')
333
+
334
+ ## Key auto.
335
+ if 'key_auto' in kwargs:
336
+ kwargs['sa_column_kwargs']['autoincrement'] = True
337
+ else:
338
+ kwargs['sa_column_kwargs']['autoincrement'] = False
339
+
340
+ ## Non null.
341
+ if 'non_null' in kwargs:
342
+ kwargs['nullable'] = not kwargs.pop('non_null')
343
+ else:
344
+ kwargs['nullable'] = True
158
345
 
346
+ ## Comment.
347
+ if 'comment' in kwargs:
348
+ kwargs['sa_column_kwargs']['comment'] = kwargs.pop('comment')
159
349
 
160
- ModelT = TypeVar('ModelT', bound=DatabaseORMModel)
350
+ # Base.
351
+ super().__init__(**kwargs)
161
352
 
162
353
 
163
354
  class DatabaseORM(DatabaseORMBase):
@@ -171,8 +362,9 @@ class DatabaseORM(DatabaseORMBase):
171
362
  """
172
363
 
173
364
  Model = DatabaseORMModel
174
- Field = sqlmodel_Field
365
+ Field = DatabaseORMModelField
175
366
  Config = ConfigDict
367
+ tyeps = sqltypes
176
368
  wrap_validate_filed = pydantic_field_validator
177
369
  wrap_validate_model = pydantic_model_validator
178
370
 
@@ -196,9 +388,6 @@ class DatabaseORM(DatabaseORMBase):
196
388
  self.all = self._session.all
197
389
  self.add = self._session.add
198
390
 
199
- ## Avoid descriptor error.
200
- self.Field = sqlmodel_Field
201
-
202
391
 
203
392
  def session(self, autocommit: bool = False):
204
393
  """
@@ -230,13 +419,17 @@ class DatabaseORM(DatabaseORMBase):
230
419
  Parameters
231
420
  ----------
232
421
  models : ORM model instances.
233
- check : Skip existing table.
422
+ check : Skip existing table and not mapping model.
234
423
  """
235
424
 
236
425
  # Create.
237
426
  for model in models:
238
427
  table = model.table()
239
- table.create(self.db.engine, checkfirst=skip)
428
+ if (
429
+ not skip
430
+ or table is not None
431
+ ):
432
+ table.create(self.db.engine, checkfirst=skip)
240
433
 
241
434
 
242
435
  def drop(
@@ -250,13 +443,17 @@ class DatabaseORM(DatabaseORMBase):
250
443
  Parameters
251
444
  ----------
252
445
  models : ORM model instances.
253
- check : Skip not exist table.
446
+ check : Skip not exist table and not mapping model.
254
447
  """
255
448
 
256
449
  # Create.
257
450
  for model in models:
258
451
  table = model.table()
259
- table.drop(self.db.engine, checkfirst=skip)
452
+ if (
453
+ not skip
454
+ or table is not None
455
+ ):
456
+ table.drop(self.db.engine, checkfirst=skip)
260
457
 
261
458
 
262
459
  class DataBaseORMSession(DatabaseORMBase):
@@ -704,13 +901,13 @@ class DatabaseORMStatement(DatabaseORMBase):
704
901
  model : ORM model instance.
705
902
  """
706
903
 
904
+ # Base.
905
+ super().__init__(self.model)
906
+
707
907
  # Build.
708
908
  self.sess = sess
709
909
  self.model = model
710
910
 
711
- # Init.
712
- super().__init__(self.model)
713
-
714
911
 
715
912
  def execute(self) -> None:
716
913
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reydb
3
- Version: 1.1.52
3
+ Version: 1.1.53
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,17 @@
1
+ reydb/__init__.py,sha256=vwShFPkCDpLTrVGCq1AZgKCGQ8tBBodCxrvrib9ptrs,574
2
+ reydb/rall.py,sha256=GsXHqvT1k--U53HpDY4SALjIHN8rwgSxeXpJjH5gq2E,409
3
+ reydb/rbase.py,sha256=rgAkEHLXDoMfiNCN2ckPQD-Eyd1tp0f122LEbI7L1Qg,8947
4
+ reydb/rbuild.py,sha256=6N8aLqCeX8JnOwQstVA2AuM0Rl5kUHx5Enrm2GGcGvo,31852
5
+ reydb/rconfig.py,sha256=UTpJ9psCrQlFx3FJ5_B8WkURRQ5PD6ZHLYg7MQRebmU,12659
6
+ reydb/rconn.py,sha256=Hsr4DIlQ1vFstveYnKaxAMgn18T-ggCwuUMDJi9qGNQ,6542
7
+ reydb/rdb.py,sha256=bMv98QNWYzVn6EFX9JiyihiJ5n-BZVJH8mTzkkReyaU,14948
8
+ reydb/rerror.py,sha256=Lsl7UECYdIFYjd9t7RhvNcHdyGStI3gffm8zmkK1DEc,9943
9
+ reydb/rexec.py,sha256=Q2__f_2-nnx-ESNZwBUUMq7WJztqhYeK8HehyiuVqlw,53981
10
+ reydb/rfile.py,sha256=RI1jMsNNJWvdky3oRV1Gw-9-tc1F92QjD24s2eusCVI,15184
11
+ reydb/rinfo.py,sha256=4btKBBZzVXGuPsmswqXDxvjZQuAc9raQ0tpXvmft71s,12741
12
+ reydb/rorm.py,sha256=JUwKZ9OgrI_FvTwTDfZhozpJB1v1xk_o3ESPLGTXXYI,23693
13
+ reydb/rparam.py,sha256=six7wwQRKycoscv-AGyQqsPjA4_TZgcGQ_jk7FZytQs,6803
14
+ reydb-1.1.53.dist-info/METADATA,sha256=UAgUFGAEId9qYGrK4ojOZeNZV61a3tp09leBSNdIGXU,1550
15
+ reydb-1.1.53.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ reydb-1.1.53.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
17
+ reydb-1.1.53.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- reydb/__init__.py,sha256=vwShFPkCDpLTrVGCq1AZgKCGQ8tBBodCxrvrib9ptrs,574
2
- reydb/rall.py,sha256=GsXHqvT1k--U53HpDY4SALjIHN8rwgSxeXpJjH5gq2E,409
3
- reydb/rbase.py,sha256=A7or663TcrQyq56P813WsV4BlApZIzXOPdZLsT7KwWw,7040
4
- reydb/rbuild.py,sha256=6N8aLqCeX8JnOwQstVA2AuM0Rl5kUHx5Enrm2GGcGvo,31852
5
- reydb/rconfig.py,sha256=kkqJg68bGZTE3JqH9dF1n-c1shuPJ4O8Bqg7J9Pd2CM,12659
6
- reydb/rconn.py,sha256=AYGi_A4qMMHEAiH0lGtHpH2Q3PZylNFoBjGtXeDSNlA,2810
7
- reydb/rdb.py,sha256=ZtEb6LSL4yFw5pnolqL39fr7BgeGMMUk-OYotpx_Mrw,12916
8
- reydb/rerror.py,sha256=Lsl7UECYdIFYjd9t7RhvNcHdyGStI3gffm8zmkK1DEc,9943
9
- reydb/rexec.py,sha256=z82pYvtFQmYaKWeo26G7jT2f3f9IyxCPfF4n5Cf0LcM,31222
10
- reydb/rfile.py,sha256=8HSrlpuslSCcWzjeh2y4Fs7R_qnm3jS_c13CDrKxpaw,15182
11
- reydb/rinfo.py,sha256=4btKBBZzVXGuPsmswqXDxvjZQuAc9raQ0tpXvmft71s,12741
12
- reydb/rorm.py,sha256=DvRBRPdvfq019CZV21OJoTdcqicDZUBdSMzlikTFLXg,16563
13
- reydb/rparam.py,sha256=six7wwQRKycoscv-AGyQqsPjA4_TZgcGQ_jk7FZytQs,6803
14
- reydb-1.1.52.dist-info/METADATA,sha256=bNFHLGFuX0lblm5mSXi_Es8l0nHOLdt12-fSh54BaNU,1550
15
- reydb-1.1.52.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- reydb-1.1.52.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
17
- reydb-1.1.52.dist-info/RECORD,,
File without changes