Aestate
__init__.py
Go to the documentation of this file.
1 import copy
2 from datetime import datetime
3 
4 from typing import List, Tuple
5 
6 from aestate.dbs import base
7 from aestate.exception import FieldNotExist
8 from aestate.dbs._mysql import tag
9 from aestate.util import others
10 from aestate.util.Log import ALog
11 import threading
12 from aestate.work.Modes import Singleton
13 
14 
15 class ParseUtil:
16 
17  def parse_main(self, *args, to_str=False, symbol='%s', left='`', right='`', **kwargs):
18  """
19  解析属性:
20  将属性格式设置为:['`a`,','`b`,','`c`']
21  :param to_str:是否转成str格式
22  :param args:参数
23  :param symbol:分隔符语法
24  :param left:分隔符语法
25  :param right:分隔符语法
26  :return:
27  """
28 
29  is_field = kwargs['is_field'] if 'is_field' in kwargs.keys() else False
30 
31  fields = []
32  for value in args:
33  value = others.conversion_types(value)
34  if to_str:
35  if is_field:
36  fields.append(f'{left}{symbol}{right},' % (str(value)))
37  else:
38  fields.append(f'{symbol},' % (str(value)))
39  else:
40  fields.append(value if not ParseUtil.is_default(value) else None)
41  if len(fields) != 0:
42  fields[len(fields) - 1] = fields[len(fields) - 1].replace(',', '')
43  field_str = ''
44  # 转成字符串的话 "`field1`,`field2`,`field3`"
45  if to_str:
46  for field in fields:
47  field_str += field
48  return field_str
49  return fields
50  else:
51  return None
52 
53  def parse_key(self, *args, **kwargs):
54  """
55  如果 is_field=True `field` [field]
56 
57 
58  解析键格式,如:
59  INSERT INTO `demo` (这里的就是键) VALUES ('','','','');
60  :param args:
61  :return:
62  """
63  if 'is_field' not in kwargs.keys():
64  kwargs['is_field'] = True
65  fields = self.parse_main(*args, to_str=True, **kwargs)
66  return fields
67 
68  def parse_update(self, pojo, key):
69  f = pojo.sqlFields
70  kes = [f.update_str, f.left_subscript, pojo.__table_name__, f.right_subscript, f.set_str]
71  params = []
72  for i in pojo.fields:
73  if i != key and not pojo.getFields()[i].auto_time:
74  kes.append(f'`{i}`=%s')
75  kes.append(", ")
76  if pojo.getFields()[i].update_auto_time:
77  params.append(datetime.now())
78  else:
79  params.append(getattr(pojo, i))
80  kes = kes[:-1]
81  kes.append(f.where_str)
82  kes.append(f'`{key}`=%s')
83  params.append(getattr(pojo, key))
84  sql = ''.join(kes)
85  return sql, params
86 
87  def parse_remove(self, pojo, key):
88  f = pojo.sqlFields
89  kes = [f.delete_str, f.from_str, f.left_subscript, pojo.__table_name__, f.right_subscript, f.where_str]
90  params = []
91  kes.append(f'`{key}`=%s')
92  params.append(getattr(pojo, key))
93  sql = ''.join(kes)
94  return sql, params
95 
96  def parse_value(self, *args, **kwargs):
97  """
98  解析值格式,如:
99  INSERT INTO `demo` (`index`, `title`, `selects`, `success`) VALUES (这里的就是值);
100  :param args:
101  :return:
102  """
103  values = self.parse_main(*args, **kwargs)
104  return values
105 
106  def parse_insert(self, keys, values, __table_name__, insert_str, values_str, symbol='%s',
107  sql_format='%s %s (%s)%s(%s)'):
108  """
109  实现此方法可自定义sql生成模式
110 
111  keys:包含了所有需要解析的字段名
112  values:包含了所有需要用到的字段的值
113  __table_name__:表名称
114  insert_str:insert的字符串
115  values_str:values字符串
116  symbol:格式化方式,以`%s`作为匿名符号
117  """
118  fields = self.parse_key(*keys)
119  values = self.parse_value(*values)
120  # 分析需要几个隐藏值
121  hides_value = [f'{symbol},' for i in range(len(values))]
122  # 去除末尾的逗号
123  end = hides_value[len(hides_value) - 1]
124  hides_value[len(hides_value) - 1] = end[0: len(end) - 1]
125  # 得到最后隐藏符号的字符串表达格式
126  value = ''.join(hides_value)
127  sql = sql_format % (
128  insert_str,
129  str(__table_name__), fields, values_str, value
130  )
131 
132  kes = {'sql': sql}
133  args = []
134  [args.append(i) for i in values]
135  kes['params'] = args
136  return kes
137 
138  def parse_insert_pojo(self, pojo, __table_name__, insert_str, values_str):
139  """
140  解析插入语句
141 
142  INSERT INTO `__table_name__`(`title`,'selects') VALUE ('','')
143 
144  :param pojo:POJO对象
145  :param __table_name__:表名
146  :param insert_str:insert的sql方言
147  :param values_str:values的sql方言
148  :return:
149  """
150  # 得到所有的键
151  ParseUtil.fieldExist(pojo, 'fields', raise_exception=True)
152  # 在得到值之后解析是否为空并删除为空的值和对应的字段
153  cp_value = []
154  # 复制新的一张字段信息
155  keys_copy = []
156 
157  keys_c, cp_v = ParseUtil.parse_pojo(pojo)
158  keys_copy += keys_c
159  cp_value += cp_v
160 
161  return self.parse_insert(keys_copy, cp_value, __table_name__, insert_str=insert_str,
162  values_str=values_str)
163 
164  @staticmethod
165  def parse_pojo(pojo) -> Tuple[list, list]:
166  keys = pojo.fields
167  # 在得到值之后解析是否为空并删除为空的值和对应的字段
168  cp_value = []
169  # 复制新的一张字段信息
170  keys_copy = []
171  values = [getattr(pojo, v) for v in keys]
172  for i, j in enumerate(values):
173  if j is not None and not ParseUtil.is_default(j):
174  keys_copy.append(keys[i])
175  cp_value.append(j)
176 
177  return keys_copy, cp_value
178 
179  @staticmethod
180  def parse_obj(data: dict, instance: object) -> object:
181  """
182  将数据解析成对象
183  注意事项:
184  数据来源必须是DbUtil下查询出来的
185  :param data:单行数据
186  :param instance:参与解析的对象
187  :return:POJO对象
188  """
189  # 深度复制对象
190  part_obj = copy.copy(instance)
191  for key, value in data.items():
192  setattr(part_obj, key, value)
193  return part_obj
194 
195  @staticmethod
196  def find_last_id(**kwargs):
197  """作者:CACode 最后编辑于2021/4/12
198 
199  遵循规则:
200 
201  内部>配置文件
202 
203  是否包含返回最后一行ID的配置
204 
205  只存在于更新操做的方法内,如:
206 
207  insert,
208 
209  update,
210 
211  delete
212 
213  Attributes:
214 
215  conf_obj:配置类
216  """
217  conf_obj = kwargs['config_obj']
218  if 'last_id' not in kwargs.keys():
219  c_dict = conf_obj.get_dict()
220  if 'last_id' in c_dict.keys():
221  kwargs['last_id'] = c_dict['last_id']
222  else:
223  kwargs['last_id'] = False
224  return kwargs
225 
226  @staticmethod
227  def find_print_sql(**kwargs):
228  """
229  遵循规则:
230  内部>配置文件
231 
232  是否包含打印sql的配置
233 
234  存在于所有数据库操做
235 
236  Attributes:
237  conf_obj:配置类
238  """
239  conf_obj = kwargs['config_obj']
240  if 'print_sql' not in kwargs.keys():
241  c_dict = conf_obj.get_dict()
242  if 'print_sql' in c_dict.keys():
243  kwargs['print_sql'] = c_dict['print_sql']
244  else:
245  kwargs['print_sql'] = False
246  return kwargs
247 
248  @staticmethod
249  def case_name(text, rep_text='_', lower=True, upper=False):
250  """
251  将驼峰文本改为使用指定符号分割的字符串表达形式并全部小写
252  :param text:需要替换的文本
253  :param rep_text:在大写文本后面追加的字符串
254  :param lower:是否需要全部小写
255  :param upper:是否需要全部大写
256  """
257  lst = []
258  for index, char in enumerate(text):
259  if char.isupper() and index != 0:
260  lst.append(rep_text)
261  lst.append(char)
262  # 替换名称
263  if lower:
264  return "".join(lst).lower()
265  elif upper:
266  return "".join(lst).upper()
267  else:
268  return "".join(lst)
269 
270  @staticmethod
271  def is_default(__val):
272  """
273  是否等于默认值
274  """
275  try:
276  t_v = __val.__class__.__base__
277  if t_v in [tag.Template, tag.baseTag]:
278  return __val.default is None
279  except SyntaxError:
280  return False
281 
282  @staticmethod
283  def set_field(obj, key, value):
284  """
285  当对象没有这个字段时,为对象设置一个字段
286 
287  为了方便提高拓展性可解耦,框架内部务必使用此
288 
289  方法或者set_field_compulsory()为操作管理类提供对象
290 
291  """
292  if not hasattr(obj, key):
293  setattr(obj, key, value)
294 
295  @staticmethod
296  def set_field_compulsory(obj, key: str, data: dict, val: object) -> None:
297  """
298  如果键存在于data中,为obj插入该值,反之插入val
299  """
300  if key in data.keys():
301  setattr(obj, key, data[key])
302  else:
303  setattr(obj, key, val)
304 
305  @staticmethod
306  def fieldExist(obj: object, field: str, el=None, raise_exception=False) -> object:
307  """
308  在对象中获取一个字段的值,如果这个字段不存在,则将值设置为`el`
309  """
310  if isinstance(obj, dict):
311  if field in obj.keys():
312  return obj[field]
313  else:
314  if raise_exception:
315  raise ALog.log_error(
316  msg=f'the key of `{field}` cannot be found in the `{obj.__class__.__name__}`',
317  obj=FieldNotExist,
318  raise_exception=True)
319  else:
320  return el
321  else:
322  if hasattr(obj, field):
323  return getattr(obj, field)
324  else:
325  if raise_exception:
326  raise ALog.log_error(
327  msg=f'the key of `{field}` cannot be found in the `{obj.__class__.__name__}`',
328  obj=FieldNotExist,
329  raise_exception=True)
330  else:
331  return el
332 
333  @staticmethod
334  def parse_pojo_many(pojo_many: list) -> List[tuple]:
335 
336  # 在得到值之后解析是否为空并删除为空的值和对应的字段
337  cp_value = []
338  for pojo in pojo_many:
339  keys_c, cp_v = ParseUtil.parse_pojo(pojo)
340  cp_value.append(tuple(cp_v))
341  # 真实值
342  return cp_value
343 
344  @staticmethod
345  def insert_to_obj(obj, kwargs):
346  for key, value in kwargs.items():
347  ParseUtil.set_field_compulsory(obj=obj, key=key, data=kwargs, val=value)
348 
349  def get_pojo_sql(self, instance):
350  """
351  获取创建pojo对象的sql语句
352  """
353  fields = instance.getFields()
354  print(fields)
355 
356 
357 # 所有常量以空格开头并且以空格结束
358 # 空格符
359 class Fields:
360  """
361  默认的数据库方言配置
362  """
363 
364  _instance_lock = threading.RLock()
365 
366  @staticmethod
367  def parse_field(key: str) -> str:
368  return f' {key} '
369 
370  @property
371  def left_subscript(self):
372  """
373  左角标
374  """
375  return '`'
376 
377  @property
378  def space(self):
379  """
380  空格
381  """
382  return ' '
383 
384  @property
385  def right_subscript(self):
386  """
387  右角标
388  """
389  return '`'
390 
391  @property
392  def insert_str(self):
393  """
394  插入
395  """
396  return self.parse_field('INSERT INTO')
397 
398  @property
399  def delete_str(self):
400  """
401  删除
402  """
403  return self.parse_field('DELETE')
404 
405  @property
406  def update_str(self):
407  """
408  更新
409  """
410  return self.parse_field('UPDATE')
411 
412  @property
413  def find_str(self):
414  return self.parse_field('SELECT')
415 
416  @property
417  def where_str(self):
418  return self.parse_field('WHERE')
419 
420  @property
421  def by_str(self):
422  return self.parse_field('BY')
423 
424  @property
425  def order_by_str(self):
426  return self.parse_field('ORDER BY')
427 
428  @property
429  def group_by_str(self):
430  return self.parse_field('GROUP BY')
431 
432  @property
433  def desc_str(self):
434  return self.parse_field('DESC')
435 
436  @property
437  def set_str(self):
438  return self.parse_field('SET')
439 
440  @property
441  def ander_str(self):
442  return self.parse_field('AND')
443 
444  @property
445  def limit_str(self):
446  return self.parse_field('LIMIT')
447 
448  @property
449  def from_str(self):
450  return self.parse_field('FROM')
451 
452  @property
453  def value_str(self):
454  return self.parse_field('VALUE')
455 
456  @property
457  def values_str(self):
458  return self.parse_field('VALUES')
459 
460  @property
461  def asses_str(self):
462  return self.parse_field('AS')
463 
464  @property
465  def left_par(self):
466  return self.parse_field('(')
467 
468  @property
469  def right_par(self):
470  return self.parse_field(')')
471 
472  @property
473  def comma(self):
474  return self.parse_field(',')
475 
476  @property
477  def eq(self):
478  return self.parse_field('=')
479 
480  @property
481  def on_str(self):
482  return self.parse_field('on')
483 
484  @property
485  def left_join_str(self):
486  return self.parse_field('LEFT JOIN')
487 
488  @property
489  def symbol(self):
490  return '>> << == <= >= != - + / * %'.split(' ')
491 
492  def __new__(cls, *args, **kwargs):
493  instance = Singleton.createObject(cls)
494  return instance
495 
496 
498 
499  def extra(self, field) -> Tuple[bool, object]:
500 
501  ver = {
502  "Field": lambda x: x['Field'] == field.name,
503  "Type":
504  lambda x: x["Type"] == field.t_type
505  if field.length is None else
506  f"{field.t_type}({field.length})"
507  if field.d_point is None else
508  f"{field.t_type}({field.length},{field.d_point})",
509 
510  "Null": {
511 
512  },
513  "Key": {
514 
515  },
516  "Default": {
517 
518  },
519  "Extra": {
520 
521  }
522  }
523 
524  ft = {
525  'Field': field.name,
526  'Type': field.t_type,
527  'Null': field.is_null,
528  'Key': field.primary_key,
529  'Default': field.default,
530  'Extra': field.comment,
531  }
532 
533  target = None
534 
535  for i in self.R:
536  if field.name == i['Field']:
537  target = i
538  break
539 
540  if target is None:
541  return False, f"Check failed:{ft}"
542  self.R.remove(target)
543 
544  for k, v in ft.items():
545  pass
546 
547  return True, f"{ft}"
548 
549  def check(self):
550  self.R = self.instance.execute_sql(f"DESC `{self.instance.get_tb_name()}`")
551  for k, v in self.instance.getFields().items():
552  f = self.extra(v)
553  ALog.log(f[1], obj=self, task_name="Check") \
554  if f[0] else \
555  ALog.log_error(f[1], obj=self, task_name="Check")
556 
557  if len(self.R) != 0:
558  ALog.log_error(f"Extra field:{self.R}", obj=self, task_name="Check")
559 
560  def create(self):
561  PRIMARYKEY = None
562  FIELDS = []
563  default_parse = lambda x: "AUTO_INCREMENT" \
564  if x.autoField else 'DEFAULT CURRENT_TIMESTAMP' \
565  if x.auto_time else 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' \
566  if x.update_auto_time else f"CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '{x.default}'" \
567  if isinstance(x.default, str) else f"DEFAULT '{x.default}'" \
568  if isinstance(x.default, int) else ""
569 
570  type_parse = lambda x: x.t_type \
571  if x.length is None else "%s(%s,%s)" % (x.t_type, x.length, x.d_point) \
572  if x.d_point is not None and x.length is not None else "%s(%s)" % (x.t_type, x.length) \
573  if x.length is not None else x.t_type
574  for k, v in self.instance._fields.items():
575  FIELDS.append(
576  "`%s` %s %s %s," %
577  (
578  v.name,
579  type_parse(v),
580  default_parse(v),
581  'NULL' if v.is_null else 'NOT NULL'
582  )
583  )
584  if v.primary_key:
585  PRIMARYKEY = v.name
586 
587  sql = "CREATE TABLE IF NOT EXISTS `%s` ( %s %s) ENGINE=InnoDB DEFAULT CHARSET=utf8;" % \
588  (self.instance.get_tb_name(), ''.join(FIELDS), "PRIMARY KEY (`%s`)" % PRIMARYKEY)
589 
590  ALog.log(sql)
591  r = self.instance.execute_sql(sql)
592  return r
aestate.dbs._mysql.OperaBase.create
def create(self)
Definition: __init__.py:560
aestate.dbs._mysql.Fields.__new__
def __new__(cls, *args, **kwargs)
Definition: __init__.py:492
aestate.dbs._mysql.Fields.asses_str
def asses_str(self)
Definition: __init__.py:461
aestate.dbs._mysql.ParseUtil.insert_to_obj
def insert_to_obj(obj, kwargs)
Definition: __init__.py:345
aestate.dbs._mysql.ParseUtil.fieldExist
object fieldExist(object obj, str field, el=None, raise_exception=False)
Definition: __init__.py:306
aestate.dbs._mysql.Fields.desc_str
def desc_str(self)
Definition: __init__.py:433
aestate.dbs._mysql.ParseUtil.parse_key
def parse_key(self, *args, **kwargs)
Definition: __init__.py:53
aestate.dbs._mysql.Fields.where_str
def where_str(self)
Definition: __init__.py:417
aestate.dbs._mysql.Fields.left_par
def left_par(self)
Definition: __init__.py:465
aestate.dbs._mysql.Fields.limit_str
def limit_str(self)
Definition: __init__.py:445
aestate.dbs._mysql.OperaBase.R
R
Definition: __init__.py:550
aestate.dbs._mysql
Definition: __init__.py:1
aestate.dbs._mysql.ParseUtil
Definition: __init__.py:15
aestate.dbs._mysql.Fields.find_str
def find_str(self)
Definition: __init__.py:413
aestate.dbs._mysql.ParseUtil.find_print_sql
def find_print_sql(**kwargs)
Definition: __init__.py:227
aestate.dbs._mysql.tag.Template
Definition: tag.py:91
aestate.dbs._mysql.ParseUtil.parse_update
def parse_update(self, pojo, key)
Definition: __init__.py:68
aestate.dbs._mysql.Fields.group_by_str
def group_by_str(self)
Definition: __init__.py:429
aestate.dbs._mysql.ParseUtil.case_name
def case_name(text, rep_text='_', lower=True, upper=False)
Definition: __init__.py:249
aestate.dbs._mysql.Fields.set_str
def set_str(self)
Definition: __init__.py:437
aestate.dbs._mysql.tag.baseTag
Definition: tag.py:10
aestate.dbs._mysql.Fields.eq
def eq(self)
Definition: __init__.py:477
aestate.dbs._mysql.Fields.symbol
def symbol(self)
Definition: __init__.py:489
aestate.dbs._mysql.ParseUtil.parse_remove
def parse_remove(self, pojo, key)
Definition: __init__.py:87
aestate.dbs._mysql.Fields.on_str
def on_str(self)
Definition: __init__.py:481
aestate.dbs._mysql.Fields.left_join_str
def left_join_str(self)
Definition: __init__.py:485
aestate.dbs._mysql.OperaBase.check
def check(self)
Definition: __init__.py:549
aestate.dbs._mysql.Fields.right_subscript
def right_subscript(self)
Definition: __init__.py:385
aestate.dbs._mysql.Fields
Definition: __init__.py:359
aestate.dbs._mysql.ParseUtil.parse_pojo_many
List[tuple] parse_pojo_many(list pojo_many)
Definition: __init__.py:334
aestate.util
Definition: __init__.py:1
aestate.dbs._mysql.Fields.order_by_str
def order_by_str(self)
Definition: __init__.py:425
aestate.dbs._mysql.Fields.space
def space(self)
Definition: __init__.py:378
aestate.dbs._mysql.ParseUtil.parse_pojo
Tuple[list, list] parse_pojo(pojo)
Definition: __init__.py:165
aestate.dbs._mysql.ParseUtil.set_field
def set_field(obj, key, value)
Definition: __init__.py:283
aestate.util.Log
Definition: Log.py:1
aestate.dbs._mysql.ParseUtil.parse_obj
object parse_obj(dict data, object instance)
Definition: __init__.py:180
aestate.work.Modes
Definition: Modes.py:1
aestate.dbs._mysql.Fields.update_str
def update_str(self)
Definition: __init__.py:406
aestate.exception
Definition: __init__.py:1
aestate.dbs._mysql.Fields.comma
def comma(self)
Definition: __init__.py:473
aestate.dbs._mysql.Fields.by_str
def by_str(self)
Definition: __init__.py:421
aestate.dbs._mysql.ParseUtil.parse_insert_pojo
def parse_insert_pojo(self, pojo, __table_name__, insert_str, values_str)
Definition: __init__.py:138
aestate.dbs
Definition: __init__.py:1
aestate.dbs._mysql.ParseUtil.parse_main
def parse_main(self, *args, to_str=False, symbol='%s', left='`', right='`', **kwargs)
Definition: __init__.py:17
aestate.dbs._mysql.ParseUtil.get_pojo_sql
def get_pojo_sql(self, instance)
Definition: __init__.py:349
aestate.dbs._mysql.ParseUtil.is_default
def is_default(__val)
Definition: __init__.py:271
aestate.dbs._mysql.Fields.delete_str
def delete_str(self)
Definition: __init__.py:399
aestate.dbs._mysql.Fields.values_str
def values_str(self)
Definition: __init__.py:457
aestate.dbs._mysql.Fields.parse_field
str parse_field(str key)
Definition: __init__.py:367
aestate.dbs._mysql.ParseUtil.set_field_compulsory
None set_field_compulsory(obj, str key, dict data, object val)
Definition: __init__.py:296
aestate.dbs._mysql.Fields.left_subscript
def left_subscript(self)
Definition: __init__.py:371
aestate.dbs._mysql.OperaBase
Definition: __init__.py:497
aestate.dbs._mysql.OperaBase.extra
Tuple[bool, object] extra(self, field)
Definition: __init__.py:499
aestate.dbs._mysql.Fields.insert_str
def insert_str(self)
Definition: __init__.py:392
aestate.dbs._mysql.Fields.ander_str
def ander_str(self)
Definition: __init__.py:441
aestate.dbs.base.OperaBase.instance
instance
Definition: base.py:6
aestate.dbs._mysql.ParseUtil.parse_insert
def parse_insert(self, keys, values, __table_name__, insert_str, values_str, symbol='%s', sql_format='%s %s(%s)%s(%s)')
Definition: __init__.py:106
aestate.dbs._mysql.Fields.value_str
def value_str(self)
Definition: __init__.py:453
aestate.dbs._mysql.ParseUtil.find_last_id
def find_last_id(**kwargs)
Definition: __init__.py:196
aestate.dbs._mysql.ParseUtil.parse_value
def parse_value(self, *args, **kwargs)
Definition: __init__.py:96
aestate.dbs._mysql.Fields.from_str
def from_str(self)
Definition: __init__.py:449
aestate.dbs.base.OperaBase
Definition: base.py:4
aestate.dbs._mysql.Fields.right_par
def right_par(self)
Definition: __init__.py:469