cloudoll 2.4.0__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.
- cloudoll/__init__.py +1 -0
- cloudoll/__main__.py +4 -0
- cloudoll/cli.py +76 -0
- cloudoll/error/__init__.py +0 -0
- cloudoll/error/errors.py +48 -0
- cloudoll/logging/__init__.py +188 -0
- cloudoll/mail/__init__.py +0 -0
- cloudoll/mail/smtp.py +197 -0
- cloudoll/orm/__init__.py +252 -0
- cloudoll/orm/base.py +80 -0
- cloudoll/orm/err.py +2 -0
- cloudoll/orm/field.py +522 -0
- cloudoll/orm/model.py +806 -0
- cloudoll/orm/mysql.py +84 -0
- cloudoll/orm/parse.py +139 -0
- cloudoll/orm/postgres.py +70 -0
- cloudoll/robot/__init__.py +0 -0
- cloudoll/robot/dingtalk.py +209 -0
- cloudoll/robot/feishu.py +102 -0
- cloudoll/robot/slack.py +115 -0
- cloudoll/utils/__init__.py +0 -0
- cloudoll/utils/cli_main.py +72 -0
- cloudoll/utils/cli_mian.py +74 -0
- cloudoll/utils/common.py +57 -0
- cloudoll/utils/m2d.py +311 -0
- cloudoll/utils/patch_loop.py +222 -0
- cloudoll/utils/snowflake.py +86 -0
- cloudoll/utils/watch.py +194 -0
- cloudoll/web/__init__.py +53 -0
- cloudoll/web/core.py +557 -0
- cloudoll/web/exception.py +63 -0
- cloudoll/web/html.py +93 -0
- cloudoll/web/http.py +79 -0
- cloudoll/web/jwt.py +40 -0
- cloudoll/web/requests.py +161 -0
- cloudoll/web/settings.py +22 -0
- cloudoll-2.4.0.dist-info/METADATA +414 -0
- cloudoll-2.4.0.dist-info/RECORD +42 -0
- cloudoll-2.4.0.dist-info/WHEEL +6 -0
- cloudoll-2.4.0.dist-info/entry_points.txt +2 -0
- cloudoll-2.4.0.dist-info/licenses/LICENSE +21 -0
- cloudoll-2.4.0.dist-info/top_level.txt +1 -0
cloudoll/orm/model.py
ADDED
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
from .field import Field, Function, Expression
|
|
2
|
+
from ..logging import warning
|
|
3
|
+
from functools import reduce
|
|
4
|
+
import operator
|
|
5
|
+
import copy
|
|
6
|
+
import re
|
|
7
|
+
import datetime
|
|
8
|
+
from ..utils.common import Object
|
|
9
|
+
from typing import Tuple
|
|
10
|
+
|
|
11
|
+
__ALL__ = ("models", "Model")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ModelMetaclass(type):
|
|
15
|
+
# def __init__(self, **kw):
|
|
16
|
+
# pass
|
|
17
|
+
# def __call__(cls, *args, **kwargs):
|
|
18
|
+
# instance = super().__call__(*args, **kwargs)
|
|
19
|
+
# # 在元类中处理拷贝逻辑
|
|
20
|
+
# return copy.copy(instance)
|
|
21
|
+
|
|
22
|
+
def __new__(mcs, name, bases, attrs):
|
|
23
|
+
if name == "Model":
|
|
24
|
+
return type.__new__(mcs, name, bases, attrs)
|
|
25
|
+
# debug("Found model:%s" % name)
|
|
26
|
+
# 表名
|
|
27
|
+
table_name = attrs.get("__table__", None) or name
|
|
28
|
+
primary_key = None
|
|
29
|
+
fields = []
|
|
30
|
+
# mappings = dict()
|
|
31
|
+
for k, v in attrs.items():
|
|
32
|
+
if isinstance(v, Field):
|
|
33
|
+
v.name = k
|
|
34
|
+
v.full_name = f"`{table_name}`.{k}"
|
|
35
|
+
# mappings[k] = v
|
|
36
|
+
if v.primary_key:
|
|
37
|
+
if primary_key:
|
|
38
|
+
warning(f"Duplicate primary key for {table_name}")
|
|
39
|
+
primary_key = k
|
|
40
|
+
# else:
|
|
41
|
+
fields.append(k)
|
|
42
|
+
|
|
43
|
+
if not primary_key:
|
|
44
|
+
warning(f"{table_name} Missing primary key")
|
|
45
|
+
|
|
46
|
+
# for k in mappings.keys():
|
|
47
|
+
# attrs.pop(k)
|
|
48
|
+
|
|
49
|
+
# escaped_fields = list(map(lambda f: "`%s`" % f, fields))
|
|
50
|
+
# attrs["__mappings__"] = mappings
|
|
51
|
+
attrs["__table__"] = table_name
|
|
52
|
+
attrs["__primary_key__"] = primary_key
|
|
53
|
+
attrs["__fields__"] = fields
|
|
54
|
+
attrs["__pool__"] = None
|
|
55
|
+
attrs["__join__"] = None
|
|
56
|
+
attrs["__where__"] = None
|
|
57
|
+
attrs["__having__"] = None
|
|
58
|
+
attrs["__params__"] = None
|
|
59
|
+
attrs["__cols__"] = "*"
|
|
60
|
+
attrs["__order_by__"] = None
|
|
61
|
+
attrs["__group_by__"] = None
|
|
62
|
+
attrs["__limit__"] = None
|
|
63
|
+
attrs["__offset__"] = None
|
|
64
|
+
|
|
65
|
+
model = type.__new__(mcs, name, bases, attrs)
|
|
66
|
+
return model
|
|
67
|
+
|
|
68
|
+
def __repr__(self):
|
|
69
|
+
return "<Model: %s>" % self.__name__
|
|
70
|
+
|
|
71
|
+
# def __getattr__(self, name):
|
|
72
|
+
# return self.__fields__[name]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class Model(metaclass=ModelMetaclass):
|
|
76
|
+
def __init__(self, **kw):
|
|
77
|
+
for k in self.__fields__:
|
|
78
|
+
f = getattr(self, k, None)
|
|
79
|
+
f.value = None
|
|
80
|
+
for k, v in kw.items():
|
|
81
|
+
self[k] = v
|
|
82
|
+
|
|
83
|
+
# super().__init__(self, **kw)
|
|
84
|
+
|
|
85
|
+
def __str__(self):
|
|
86
|
+
return "<Model: %s>" % self.__class__.__name__
|
|
87
|
+
|
|
88
|
+
def __repr__(self):
|
|
89
|
+
return "<Model: %s>" % self.__class__.__name__
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def __dict__(self):
|
|
93
|
+
fields = self.__fields__
|
|
94
|
+
_dict = {}
|
|
95
|
+
for key in fields:
|
|
96
|
+
f = getattr(self, key)
|
|
97
|
+
_dict[key] = f.value
|
|
98
|
+
return _dict
|
|
99
|
+
|
|
100
|
+
# class to fun for cls(**)
|
|
101
|
+
def __call__(self, **kw):
|
|
102
|
+
self.__init__(**kw)
|
|
103
|
+
|
|
104
|
+
return self
|
|
105
|
+
|
|
106
|
+
def __getitem__(self, name):
|
|
107
|
+
return getattr(self, name)
|
|
108
|
+
|
|
109
|
+
# # .['x']
|
|
110
|
+
def __setitem__(self, name, value):
|
|
111
|
+
setattr(self, name, value)
|
|
112
|
+
|
|
113
|
+
def __setattr__(self, name, value):
|
|
114
|
+
if hasattr(self, name):
|
|
115
|
+
f = getattr(self, name)
|
|
116
|
+
if isinstance(f, Field):
|
|
117
|
+
s = copy.copy(f)
|
|
118
|
+
s.value = value
|
|
119
|
+
super().__setattr__(name, s)
|
|
120
|
+
else:
|
|
121
|
+
super().__setattr__(name, value)
|
|
122
|
+
else:
|
|
123
|
+
super().__setattr__(name, value)
|
|
124
|
+
|
|
125
|
+
# for get
|
|
126
|
+
def get(self, k, d=None):
|
|
127
|
+
f = getattr(self, k)
|
|
128
|
+
if isinstance(f, Field):
|
|
129
|
+
return f.value or d
|
|
130
|
+
return f or d
|
|
131
|
+
|
|
132
|
+
def _get_primary(self):
|
|
133
|
+
pk = self.__primary_key__
|
|
134
|
+
if pk is None:
|
|
135
|
+
return None, None
|
|
136
|
+
pkf = getattr(self, pk)
|
|
137
|
+
return pk, pkf.value
|
|
138
|
+
|
|
139
|
+
def _reset(self):
|
|
140
|
+
self.__join__ = None
|
|
141
|
+
self.__where__ = None
|
|
142
|
+
self.__having__ = None
|
|
143
|
+
self.__params__ = None
|
|
144
|
+
self.__cols__ = "*"
|
|
145
|
+
self.__order_by__ = None
|
|
146
|
+
self.__group_by__ = None
|
|
147
|
+
self.__limit__ = None
|
|
148
|
+
self.__offset__ = None
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def use(cls, pool=None):
|
|
152
|
+
cls.__pool__ = pool
|
|
153
|
+
cls.__ispg = cls.__pool__.driver == "postgres" if pool else False
|
|
154
|
+
return cls()
|
|
155
|
+
|
|
156
|
+
def select(cls, *args):
|
|
157
|
+
cols = []
|
|
158
|
+
for col in args:
|
|
159
|
+
if isinstance(col, Field):
|
|
160
|
+
cols.append(col.name if cls.__ispg else col.full_name)
|
|
161
|
+
elif isinstance(col, Function):
|
|
162
|
+
q, p = col.sql()
|
|
163
|
+
cols.append(q)
|
|
164
|
+
elif isinstance(col, Expression):
|
|
165
|
+
q, p = col.sql()
|
|
166
|
+
cols.append(q)
|
|
167
|
+
cls._merge_params(p)
|
|
168
|
+
cls.__cols__ = ",".join(cols) if len(cols) else "*"
|
|
169
|
+
return cls
|
|
170
|
+
|
|
171
|
+
def join(cls, model, *exp):
|
|
172
|
+
ex = reduce(operator.and_, exp)
|
|
173
|
+
if isinstance(ex, Expression) or isinstance(ex, Function):
|
|
174
|
+
exp, q = ex.sql()
|
|
175
|
+
cls._merge_params(q)
|
|
176
|
+
else:
|
|
177
|
+
exp = ex
|
|
178
|
+
join = f"{model.__table__} ON " + exp
|
|
179
|
+
if cls.__join__ is None:
|
|
180
|
+
cls.__join__ = join
|
|
181
|
+
else:
|
|
182
|
+
cls.__join__ += join
|
|
183
|
+
return cls
|
|
184
|
+
|
|
185
|
+
def where(self, *exp):
|
|
186
|
+
if self.__where__ is not None:
|
|
187
|
+
exp = (self.__where__,) + exp
|
|
188
|
+
self.__where__ = reduce(operator.and_, exp)
|
|
189
|
+
return self
|
|
190
|
+
|
|
191
|
+
def having(self, *exp):
|
|
192
|
+
if self.__having__ is not None:
|
|
193
|
+
exp = (self.__having__,) + exp
|
|
194
|
+
self.__having__ = reduce(operator.and_, exp)
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
def order_by(self, *args):
|
|
198
|
+
by = []
|
|
199
|
+
for f in args:
|
|
200
|
+
if isinstance(f, str):
|
|
201
|
+
by.append(f)
|
|
202
|
+
else:
|
|
203
|
+
by.append(f"{f.lhs.name if self.__ispg else f.lhs.full_name} {f.op}")
|
|
204
|
+
if self.__order_by__ is not None:
|
|
205
|
+
by = self.__order_by__ + by
|
|
206
|
+
self.__order_by__ = by
|
|
207
|
+
return self
|
|
208
|
+
|
|
209
|
+
def group_by(self, *args):
|
|
210
|
+
by = []
|
|
211
|
+
for f in args:
|
|
212
|
+
by.append(f.name if self.__ispg else f.full_name)
|
|
213
|
+
if self.__group_by__ is not None:
|
|
214
|
+
by = self.__group_by__ + by
|
|
215
|
+
self.__group_by__ = by
|
|
216
|
+
return self
|
|
217
|
+
|
|
218
|
+
def _format_data(self, action, args):
|
|
219
|
+
data = dict()
|
|
220
|
+
if args is None or not args:
|
|
221
|
+
for k in self.__fields__:
|
|
222
|
+
f = getattr(self, k)
|
|
223
|
+
x = f.value
|
|
224
|
+
data[k] = x
|
|
225
|
+
elif args and isinstance(args, dict):
|
|
226
|
+
data = args
|
|
227
|
+
else:
|
|
228
|
+
for item in args:
|
|
229
|
+
if isinstance(item, Model):
|
|
230
|
+
for k in item.__dict__:
|
|
231
|
+
if (
|
|
232
|
+
action == "u" and item[k].value is not None
|
|
233
|
+
) or action == "i":
|
|
234
|
+
data[k] = item[k]
|
|
235
|
+
|
|
236
|
+
else: # for object
|
|
237
|
+
for k, v in item.items():
|
|
238
|
+
data[k] = v
|
|
239
|
+
|
|
240
|
+
return data
|
|
241
|
+
|
|
242
|
+
def _get_update_key_args(self, action, args):
|
|
243
|
+
data = self._format_data(action, args)
|
|
244
|
+
keys = []
|
|
245
|
+
params = []
|
|
246
|
+
for k, v in data.items():
|
|
247
|
+
if isinstance(v, Field):
|
|
248
|
+
value = v.value
|
|
249
|
+
if value is None:
|
|
250
|
+
if v.created_generated == True or v.update_generated == True:
|
|
251
|
+
value = datetime.datetime.now()
|
|
252
|
+
else:
|
|
253
|
+
value = v.default
|
|
254
|
+
if value is not None:
|
|
255
|
+
keys.append("`%s`=?" % k)
|
|
256
|
+
params.append(value)
|
|
257
|
+
elif v is not None: # fix sql format %s
|
|
258
|
+
keys.append("`%s`=?" % k)
|
|
259
|
+
params.append(v)
|
|
260
|
+
return ",".join(keys), params
|
|
261
|
+
|
|
262
|
+
def _get_insert_key_args(self, action, args):
|
|
263
|
+
data = self._format_data(action, args)
|
|
264
|
+
keys = []
|
|
265
|
+
params = []
|
|
266
|
+
for k, v in data.items():
|
|
267
|
+
if isinstance(v, Field):
|
|
268
|
+
value = v.value
|
|
269
|
+
if value is None:
|
|
270
|
+
if v.created_generated == True or v.update_generated == True:
|
|
271
|
+
value = datetime.datetime.now()
|
|
272
|
+
else:
|
|
273
|
+
value = v.default
|
|
274
|
+
if value is not None:
|
|
275
|
+
keys.append(k)
|
|
276
|
+
params.append(value)
|
|
277
|
+
elif v is not None: # fix sql format %s
|
|
278
|
+
keys.append(k)
|
|
279
|
+
params.append(v)
|
|
280
|
+
return keys, params
|
|
281
|
+
|
|
282
|
+
def _get_batch_keys_values(self, items: list):
|
|
283
|
+
keys = []
|
|
284
|
+
values = []
|
|
285
|
+
item = items[0]
|
|
286
|
+
if isinstance(item, Model):
|
|
287
|
+
keys = item.__dict__.keys()
|
|
288
|
+
elif isinstance(item, dict):
|
|
289
|
+
keys = item.keys()
|
|
290
|
+
|
|
291
|
+
for item in items:
|
|
292
|
+
value = []
|
|
293
|
+
if isinstance(item, Model):
|
|
294
|
+
for k in item.__dict__:
|
|
295
|
+
value.append(item[k].value)
|
|
296
|
+
elif isinstance(item, dict): # for object
|
|
297
|
+
for k, v in item.items():
|
|
298
|
+
value.append(v)
|
|
299
|
+
value = tuple(key for key in value)
|
|
300
|
+
values.append(value)
|
|
301
|
+
return keys, values
|
|
302
|
+
|
|
303
|
+
def _merge_params(self, p):
|
|
304
|
+
if p is not None:
|
|
305
|
+
if self.__params__ is not None:
|
|
306
|
+
p = self.__params__ + p
|
|
307
|
+
self.__params__ = p
|
|
308
|
+
|
|
309
|
+
def _literal(self, op, exp):
|
|
310
|
+
if exp is not None:
|
|
311
|
+
if isinstance(exp, list):
|
|
312
|
+
return f'{op} {",".join(exp)}'
|
|
313
|
+
elif isinstance(exp, Expression) or isinstance(exp, Function):
|
|
314
|
+
q, p = exp.sql()
|
|
315
|
+
self._merge_params(p)
|
|
316
|
+
return f"{op} {q}"
|
|
317
|
+
else:
|
|
318
|
+
# return exp
|
|
319
|
+
return f"{op} {exp}"
|
|
320
|
+
return ""
|
|
321
|
+
|
|
322
|
+
def _sql(self):
|
|
323
|
+
JOIN = self._literal("LEFT JOIN", self.__join__)
|
|
324
|
+
WHERE = self._literal("WHERE", self.__where__)
|
|
325
|
+
GROUPBY = self._literal("GROUP BY", self.__group_by__)
|
|
326
|
+
HAVING = self._literal("HAVING", self.__having__)
|
|
327
|
+
ORDERBY = self._literal("ORDER BY", self.__order_by__)
|
|
328
|
+
LIMIT = self._literal("LIMIT", self.__limit__)
|
|
329
|
+
OFFSET = self._literal("OFFSET", self.__offset__)
|
|
330
|
+
aft = " ".join([JOIN, WHERE, GROUPBY, HAVING, ORDERBY, LIMIT, OFFSET])
|
|
331
|
+
return f"SELECT {self.__cols__} FROM {self.__table__} {aft}"
|
|
332
|
+
|
|
333
|
+
def limit(self, limit: int):
|
|
334
|
+
self.__limit__ = f"{limit}"
|
|
335
|
+
return self
|
|
336
|
+
|
|
337
|
+
def offset(self, offset: int):
|
|
338
|
+
self.__offset__ = f"{offset}"
|
|
339
|
+
return self
|
|
340
|
+
|
|
341
|
+
def test(self):
|
|
342
|
+
return self._sql()
|
|
343
|
+
|
|
344
|
+
async def one(self):
|
|
345
|
+
self.limit(1)
|
|
346
|
+
sql = self._sql()
|
|
347
|
+
sql = self._exchange_sql(sql)
|
|
348
|
+
args = self.__params__
|
|
349
|
+
rs = await self.__pool__.one(sql, args)
|
|
350
|
+
if rs:
|
|
351
|
+
# join 时返回dict
|
|
352
|
+
result = Object(rs) if self.__join__ is not None else self(**rs)
|
|
353
|
+
self._reset()
|
|
354
|
+
return result
|
|
355
|
+
# return self(**rs)
|
|
356
|
+
# return Object(rs)
|
|
357
|
+
# return cls(**rs)
|
|
358
|
+
return None
|
|
359
|
+
|
|
360
|
+
async def all(self):
|
|
361
|
+
sql = self._sql()
|
|
362
|
+
sql = self._exchange_sql(sql)
|
|
363
|
+
args = self.__params__
|
|
364
|
+
self._reset()
|
|
365
|
+
return await self.__pool__.all(sql, args)
|
|
366
|
+
|
|
367
|
+
def _exchange_sql(self, sql: str):
|
|
368
|
+
if self.__ispg:
|
|
369
|
+
sql = sql.replace("CURDATE()", "CURRENT_DATE")
|
|
370
|
+
sql = sql.replace("NOW()", "CURRENT_TIMESTAMP")
|
|
371
|
+
|
|
372
|
+
pattern = r"INTERVAL\s+(\d+)\s+(DAY|MONTH|YEAR|HOUR|MINUTE|SECOND)"
|
|
373
|
+
matches = re.findall(pattern, sql)
|
|
374
|
+
|
|
375
|
+
def replacement(match):
|
|
376
|
+
number = match.group(1)
|
|
377
|
+
unit = match.group(2).lower() # 转换为小写
|
|
378
|
+
return f"INTERVAL '{number} {unit}'"
|
|
379
|
+
|
|
380
|
+
if matches:
|
|
381
|
+
sql = re.sub(pattern, replacement, sql)
|
|
382
|
+
|
|
383
|
+
return sql
|
|
384
|
+
|
|
385
|
+
async def update(self, *args, **kw) -> bool:
|
|
386
|
+
"""
|
|
387
|
+
Update data
|
|
388
|
+
"""
|
|
389
|
+
table = self.__table__
|
|
390
|
+
# where = self.__where__
|
|
391
|
+
where = self._literal("WHERE", self.__where__)
|
|
392
|
+
|
|
393
|
+
keys, params = self._get_update_key_args("u", args or kw)
|
|
394
|
+
|
|
395
|
+
sql = f"update `{table}` set {keys} {where}"
|
|
396
|
+
|
|
397
|
+
if where is not None and where != "":
|
|
398
|
+
if self.__params__:
|
|
399
|
+
params += self.__params__
|
|
400
|
+
else:
|
|
401
|
+
pk, pkv = self._get_primary()
|
|
402
|
+
if pkv is None:
|
|
403
|
+
for arg in args:
|
|
404
|
+
if isinstance(arg, dict) and pk in arg:
|
|
405
|
+
pkv = arg[pk]
|
|
406
|
+
elif isinstance(arg, Model):
|
|
407
|
+
pkv = arg.get(pk)
|
|
408
|
+
|
|
409
|
+
if pkv is not None:
|
|
410
|
+
sql += f" where `{pk}`=?"
|
|
411
|
+
params.append(pkv)
|
|
412
|
+
else:
|
|
413
|
+
raise "Need where or primary key"
|
|
414
|
+
self._reset()
|
|
415
|
+
sql = self._exchange_sql(sql)
|
|
416
|
+
return await self.__pool__.update(sql, params)
|
|
417
|
+
|
|
418
|
+
async def delete(self) -> bool:
|
|
419
|
+
"""
|
|
420
|
+
Delete data
|
|
421
|
+
"""
|
|
422
|
+
table = self.__table__
|
|
423
|
+
where = self._literal("WHERE", self.__where__)
|
|
424
|
+
args = self.__params__
|
|
425
|
+
sql = f"delete from `{table}` {where}"
|
|
426
|
+
|
|
427
|
+
if where is None or where == "":
|
|
428
|
+
pk, pkv = self._get_primary()
|
|
429
|
+
if pkv is not None:
|
|
430
|
+
sql += f" where `{pk}`=?"
|
|
431
|
+
args = [pkv]
|
|
432
|
+
else:
|
|
433
|
+
raise "need where or primary key"
|
|
434
|
+
self._reset()
|
|
435
|
+
sql = self._exchange_sql(sql)
|
|
436
|
+
return await self.__pool__.delete(sql, args)
|
|
437
|
+
|
|
438
|
+
async def insert(self, *args, **kw) -> Tuple[bool, int]:
|
|
439
|
+
table = self.__table__
|
|
440
|
+
keys, params = self._get_insert_key_args("i", args or kw)
|
|
441
|
+
escape_keys = [f"`{k}`" for k in keys]
|
|
442
|
+
sql = f"insert into `{table}` ({','.join(escape_keys)}) values ({','.join(['?' for k in keys])})"
|
|
443
|
+
self._reset()
|
|
444
|
+
params = tuple(key for key in params)
|
|
445
|
+
return await self.__pool__.create(sql, params)
|
|
446
|
+
|
|
447
|
+
async def insert_batch(self, items: list):
|
|
448
|
+
table = self.__table__
|
|
449
|
+
if len(items) == 0:
|
|
450
|
+
return 0
|
|
451
|
+
keys, params = self._get_batch_keys_values(items)
|
|
452
|
+
escape_keys = [f"`{k}`" for k in keys]
|
|
453
|
+
sql = f"insert into `{table}` ({','.join(escape_keys)}) values ({','.join(['?' for k in keys])})"
|
|
454
|
+
self._reset()
|
|
455
|
+
return await self.__pool__.create_batch(sql, params)
|
|
456
|
+
|
|
457
|
+
async def count(self) -> int:
|
|
458
|
+
__where__ = copy.copy(self.__where__)
|
|
459
|
+
__join__ = copy.copy(self.__join__)
|
|
460
|
+
cls = copy.deepcopy(self)
|
|
461
|
+
JOIN = cls._literal("LEFT JOIN", __join__)
|
|
462
|
+
WHERE = cls._literal("WHERE", __where__)
|
|
463
|
+
GROUPBY = self._literal("GROUP BY", self.__group_by__)
|
|
464
|
+
aft = " ".join([JOIN, WHERE, GROUPBY])
|
|
465
|
+
sql = f"SELECT COUNT(*) FROM {cls.__table__} {aft}"
|
|
466
|
+
args = cls.__params__
|
|
467
|
+
sql = self._exchange_sql(sql)
|
|
468
|
+
if GROUPBY is not None and GROUPBY != "":
|
|
469
|
+
return await cls.__pool__.group_count(sql, args)
|
|
470
|
+
return await cls.__pool__.count(sql, args)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
class Models(object):
|
|
474
|
+
class CharField(Field):
|
|
475
|
+
def __init__(
|
|
476
|
+
self,
|
|
477
|
+
name=None,
|
|
478
|
+
primary_key=False,
|
|
479
|
+
default=None,
|
|
480
|
+
charset=None,
|
|
481
|
+
max_length=None,
|
|
482
|
+
not_null=False,
|
|
483
|
+
comment=None,
|
|
484
|
+
):
|
|
485
|
+
super().__init__(
|
|
486
|
+
name,
|
|
487
|
+
"char",
|
|
488
|
+
default,
|
|
489
|
+
primary_key,
|
|
490
|
+
charset=charset,
|
|
491
|
+
max_length=max_length,
|
|
492
|
+
not_null=not_null,
|
|
493
|
+
comment=comment,
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
class VarCharField(Field):
|
|
497
|
+
def __init__(
|
|
498
|
+
self,
|
|
499
|
+
name=None,
|
|
500
|
+
primary_key=False,
|
|
501
|
+
default=None,
|
|
502
|
+
charset=None,
|
|
503
|
+
max_length=None,
|
|
504
|
+
not_null=False,
|
|
505
|
+
comment=None,
|
|
506
|
+
):
|
|
507
|
+
super().__init__(
|
|
508
|
+
name,
|
|
509
|
+
"varchar",
|
|
510
|
+
default,
|
|
511
|
+
primary_key,
|
|
512
|
+
charset=charset,
|
|
513
|
+
max_length=max_length,
|
|
514
|
+
not_null=not_null,
|
|
515
|
+
comment=comment,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
class BooleanField(Field):
|
|
519
|
+
def __init__(
|
|
520
|
+
self, name=None, default=False, not_null=False, comment=None, unsigned=False
|
|
521
|
+
):
|
|
522
|
+
super().__init__(
|
|
523
|
+
name,
|
|
524
|
+
"boolean",
|
|
525
|
+
default,
|
|
526
|
+
not_null=not_null,
|
|
527
|
+
unsigned=unsigned,
|
|
528
|
+
comment=comment,
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
class IntegerField(Field):
|
|
532
|
+
def __init__(
|
|
533
|
+
self,
|
|
534
|
+
name=None,
|
|
535
|
+
primary_key=False,
|
|
536
|
+
default=None,
|
|
537
|
+
auto_increment=False,
|
|
538
|
+
not_null=False,
|
|
539
|
+
unsigned=False,
|
|
540
|
+
comment=None,
|
|
541
|
+
max_length=None,
|
|
542
|
+
):
|
|
543
|
+
super().__init__(
|
|
544
|
+
name,
|
|
545
|
+
"int",
|
|
546
|
+
default,
|
|
547
|
+
primary_key,
|
|
548
|
+
auto_increment=auto_increment,
|
|
549
|
+
not_null=not_null,
|
|
550
|
+
unsigned=unsigned,
|
|
551
|
+
comment=comment,
|
|
552
|
+
max_length=max_length,
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
class BigIntegerField(Field):
|
|
556
|
+
def __init__(
|
|
557
|
+
self,
|
|
558
|
+
name=None,
|
|
559
|
+
primary_key=False,
|
|
560
|
+
default=None,
|
|
561
|
+
auto_increment=False,
|
|
562
|
+
not_null=False,
|
|
563
|
+
unsigned=False,
|
|
564
|
+
comment=None,
|
|
565
|
+
max_length=None,
|
|
566
|
+
):
|
|
567
|
+
super().__init__(
|
|
568
|
+
name,
|
|
569
|
+
"bigint",
|
|
570
|
+
default,
|
|
571
|
+
primary_key,
|
|
572
|
+
auto_increment=auto_increment,
|
|
573
|
+
NOT_NULL=not_null,
|
|
574
|
+
unsigned=unsigned,
|
|
575
|
+
comment=comment,
|
|
576
|
+
max_length=max_length,
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
class DoubleField(Field):
|
|
580
|
+
def __init__(
|
|
581
|
+
self,
|
|
582
|
+
name=None,
|
|
583
|
+
default=None,
|
|
584
|
+
not_null=False,
|
|
585
|
+
max_length=None,
|
|
586
|
+
unsigned=False,
|
|
587
|
+
comment=None,
|
|
588
|
+
):
|
|
589
|
+
super().__init__(
|
|
590
|
+
name,
|
|
591
|
+
"double",
|
|
592
|
+
default,
|
|
593
|
+
NOT_NULL=not_null,
|
|
594
|
+
max_length=max_length,
|
|
595
|
+
unsigned=unsigned,
|
|
596
|
+
comment=comment,
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
class FloatField(Field):
|
|
600
|
+
def __init__(
|
|
601
|
+
self,
|
|
602
|
+
name=None,
|
|
603
|
+
default=None,
|
|
604
|
+
not_null=False,
|
|
605
|
+
max_length=None,
|
|
606
|
+
scale_length=None,
|
|
607
|
+
unsigned=False,
|
|
608
|
+
comment=None,
|
|
609
|
+
):
|
|
610
|
+
super().__init__(
|
|
611
|
+
name,
|
|
612
|
+
"float",
|
|
613
|
+
default,
|
|
614
|
+
NOT_NULL=not_null,
|
|
615
|
+
max_length=max_length,
|
|
616
|
+
scale_length=scale_length,
|
|
617
|
+
unsigned=unsigned,
|
|
618
|
+
comment=comment,
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
class NumericField(Field):
|
|
622
|
+
def __init__(
|
|
623
|
+
self,
|
|
624
|
+
name=None,
|
|
625
|
+
default=0.0,
|
|
626
|
+
not_null=False,
|
|
627
|
+
max_length=None,
|
|
628
|
+
scale_length=None,
|
|
629
|
+
unsigned=False,
|
|
630
|
+
comment=None,
|
|
631
|
+
):
|
|
632
|
+
super().__init__(
|
|
633
|
+
name,
|
|
634
|
+
"numeric",
|
|
635
|
+
default,
|
|
636
|
+
NOT_NULL=not_null,
|
|
637
|
+
unsigned=unsigned,
|
|
638
|
+
max_length=max_length,
|
|
639
|
+
scale_length=scale_length,
|
|
640
|
+
comment=comment,
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
class DecimalField(Field):
|
|
644
|
+
def __init__(
|
|
645
|
+
self,
|
|
646
|
+
name=None,
|
|
647
|
+
default=0.0,
|
|
648
|
+
not_null=False,
|
|
649
|
+
max_length=None,
|
|
650
|
+
scale_length=None,
|
|
651
|
+
unsigned=False,
|
|
652
|
+
comment=None,
|
|
653
|
+
):
|
|
654
|
+
super().__init__(
|
|
655
|
+
name,
|
|
656
|
+
"decimal",
|
|
657
|
+
default,
|
|
658
|
+
NOT_NULL=not_null,
|
|
659
|
+
unsigned=unsigned,
|
|
660
|
+
max_length=max_length,
|
|
661
|
+
scale_length=scale_length,
|
|
662
|
+
comment=comment,
|
|
663
|
+
)
|
|
664
|
+
|
|
665
|
+
class TextField(Field):
|
|
666
|
+
def __init__(
|
|
667
|
+
self,
|
|
668
|
+
name=None,
|
|
669
|
+
default=None,
|
|
670
|
+
charset=None,
|
|
671
|
+
max_length=None,
|
|
672
|
+
not_null=False,
|
|
673
|
+
comment=None,
|
|
674
|
+
):
|
|
675
|
+
super().__init__(
|
|
676
|
+
name,
|
|
677
|
+
"text",
|
|
678
|
+
default,
|
|
679
|
+
charset=charset,
|
|
680
|
+
max_length=max_length,
|
|
681
|
+
NOT_NULL=not_null,
|
|
682
|
+
comment=comment,
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
class LongTextField(Field):
|
|
686
|
+
def __init__(
|
|
687
|
+
self,
|
|
688
|
+
name=None,
|
|
689
|
+
default=None,
|
|
690
|
+
charset=None,
|
|
691
|
+
max_length=None,
|
|
692
|
+
not_null=False,
|
|
693
|
+
comment=None,
|
|
694
|
+
):
|
|
695
|
+
super().__init__(
|
|
696
|
+
name,
|
|
697
|
+
"longtext",
|
|
698
|
+
default,
|
|
699
|
+
charset=charset,
|
|
700
|
+
max_length=max_length,
|
|
701
|
+
NOT_NULL=not_null,
|
|
702
|
+
comment=comment,
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
class MediumTextField(Field):
|
|
706
|
+
def __init__(
|
|
707
|
+
self,
|
|
708
|
+
name=None,
|
|
709
|
+
default=None,
|
|
710
|
+
charset=None,
|
|
711
|
+
max_length=None,
|
|
712
|
+
not_null=False,
|
|
713
|
+
comment=None,
|
|
714
|
+
):
|
|
715
|
+
super().__init__(
|
|
716
|
+
name,
|
|
717
|
+
"mediumtext",
|
|
718
|
+
default,
|
|
719
|
+
charset=charset,
|
|
720
|
+
max_length=max_length,
|
|
721
|
+
NOT_NULL=not_null,
|
|
722
|
+
comment=comment,
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
class DatetimeField(Field):
|
|
726
|
+
def __init__(
|
|
727
|
+
self,
|
|
728
|
+
name=None,
|
|
729
|
+
default=None,
|
|
730
|
+
max_length=None,
|
|
731
|
+
not_null=False,
|
|
732
|
+
created_generated=False,
|
|
733
|
+
update_generated=False,
|
|
734
|
+
comment=None,
|
|
735
|
+
):
|
|
736
|
+
super().__init__(
|
|
737
|
+
name,
|
|
738
|
+
"datetime",
|
|
739
|
+
default,
|
|
740
|
+
max_length=max_length,
|
|
741
|
+
NOT_NULL=not_null,
|
|
742
|
+
created_generated=created_generated,
|
|
743
|
+
update_generated=update_generated,
|
|
744
|
+
comment=comment,
|
|
745
|
+
)
|
|
746
|
+
|
|
747
|
+
class DateField(Field):
|
|
748
|
+
def __init__(
|
|
749
|
+
self,
|
|
750
|
+
name=None,
|
|
751
|
+
default=None,
|
|
752
|
+
max_length=None,
|
|
753
|
+
not_null=False,
|
|
754
|
+
created_generated=False,
|
|
755
|
+
update_generated=False,
|
|
756
|
+
comment=None,
|
|
757
|
+
):
|
|
758
|
+
super().__init__(
|
|
759
|
+
name,
|
|
760
|
+
"date",
|
|
761
|
+
default,
|
|
762
|
+
max_length=max_length,
|
|
763
|
+
NOT_NULL=not_null,
|
|
764
|
+
created_generated=created_generated,
|
|
765
|
+
update_generated=update_generated,
|
|
766
|
+
comment=comment,
|
|
767
|
+
)
|
|
768
|
+
|
|
769
|
+
class TimestampField(Field):
|
|
770
|
+
def __init__(
|
|
771
|
+
self,
|
|
772
|
+
name=None,
|
|
773
|
+
default=None,
|
|
774
|
+
max_length=None,
|
|
775
|
+
not_null=False,
|
|
776
|
+
created_generated=False,
|
|
777
|
+
update_generated=False,
|
|
778
|
+
comment=None,
|
|
779
|
+
):
|
|
780
|
+
super().__init__(
|
|
781
|
+
name,
|
|
782
|
+
"timestamp",
|
|
783
|
+
default,
|
|
784
|
+
False,
|
|
785
|
+
max_length=max_length,
|
|
786
|
+
NOT_NULL=not_null,
|
|
787
|
+
created_generated=created_generated,
|
|
788
|
+
update_generated=update_generated,
|
|
789
|
+
comment=comment,
|
|
790
|
+
)
|
|
791
|
+
|
|
792
|
+
class JsonField(Field):
|
|
793
|
+
def __init__(
|
|
794
|
+
self, name=None, default=None, charset=None, not_null=False, comment=None
|
|
795
|
+
):
|
|
796
|
+
super().__init__(
|
|
797
|
+
name,
|
|
798
|
+
"json",
|
|
799
|
+
default,
|
|
800
|
+
charset=charset,
|
|
801
|
+
NOT_NULL=not_null,
|
|
802
|
+
comment=comment,
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
models = Models()
|