Aestate
repository.py
Go to the documentation of this file.
1 import copy
2 
3 from aestate.work.Modes import EX_MODEL
4 from aestate.work.Serialize import QuerySet
5 from aestate.exception import FieldNotExist
6 from aestate.dbs import _mysql
7 from aestate.work.sql import ExecuteSql, ProxyOpera
8 from aestate.util.Log import ALog
9 
10 from aestate.work.orm import AOrm
11 
12 # 每个任务唯一ID
13 import uuid
14 
15 
16 class Repository:
17  """
18  - POJO类
19  - 继承该类表名此类为数据库的pojo类
20  - 需要配合:@Table(name, msg, **kwargs)使用
21  """
22 
23  def __init__(self, config_obj=None, instance=None, log_conf=None, close_log=False, serializer=QuerySet, **kwargs):
24  """
25  通过继承此类将数据表实体化
26 
27  实体化之后你可以使用像类似find_one()等操做
28 
29  可以调用conversion()方法将其转化为ORM框架常用的样式
30 
31  无需担心类型问题,无需担心datetime无法转换
32  使用方法:
33  #加入Table注解,并标注表名与描述,因考虑使用者后期优化问题,请务必填写MSG参数
34 
35  @Table(name="demo_table", msg="demo message")
36 
37  #继承Repository并得到相对应的半自动ORM操做
38  class TestClass(Repository):
39  # 初始化并super配置
40  def __init__(self,**kwargs):
41  super(DemoTable, self).__init__(config_obj=ConF(), log_conf={
42  'path': "/log/",
43  'save_flag': True
44  }, **kwargs)
45 
46  初始化配置:
47 
48  aestate.util.Config.config的配置类,详见:aestate.work.Config.MysqlConfig
49 
50  Attributes:
51  以下的字段均可覆盖重写
52 
53  config_obj:数据源配置类
54 
55  log_conf:日志配置工具
56 
57  log_obj:日志对象
58 
59  close_log:是否关闭日志
60 
61  serializer:序列化使用的类,默认使用aestate.work.Serialize.QuerySet
62 
63  instance:实例
64 
65  __table_name__:表名称
66 
67  operation:操作类的实现
68 
69  fields:操作的字段
70 
71  sqlFields:sql方言
72 
73  :param config_obj:配置类
74  :param log_conf:日志配置类
75  :param close_log:是否关闭日志显示功能
76  :param serializer:自定义序列化器,默认使用aestate.work.Serialize.QuerySet
77  """
78  # 以下使用ParseUtil将所有参数替换为可动态修改
79  # 有没有关闭日志
80  # 数据源配置
81  if config_obj is None:
82  ALog.log_error(msg="缺少配置类`config_obj`", obj=FieldNotExist, raise_exception=True)
83  self.ParseUtil = config_obj
84  ParseUtil = self.ParseUtil
85  ParseUtil.set_field_compulsory(
86  self, key='config_obj', data=kwargs, val=config_obj)
87  # 抽象类
88  ParseUtil.set_field_compulsory(
89  obj=self, data=kwargs, key='abst', val=False)
90  # 当本类为抽象类时,仅设置所需要的值
91  ParseUtil.set_field_compulsory(
92  self, key='close_log', data=kwargs, val=close_log)
93  # 有没有表名
94  ParseUtil.set_field_compulsory(self, key='__table_name__', data=kwargs,
95  val=self.__table_name__ if hasattr(self, '__table_name__') else
96  '"__table_name__" parsing failed')
97  # 参照对象
98  # 能操作数据库的,但是没有值
99  ParseUtil.set_field_compulsory(
100  self, key='instance', data=kwargs, val=instance)
101  # 取得字段的名称
102  ParseUtil.set_field_compulsory(
103  self, key='fields', data=kwargs, val=list(self.instance.getFields().keys()))
104  # 获取sql方言配置
105  ParseUtil.set_field_compulsory(
106  self, key='sqlFields', data=self.config_obj.__dict__, val=_mysql.Fields())
107  # 当当前类为抽象类时,为类取消初始化数据库配置
108  # 最后的执行结果
109  ParseUtil.set_field_compulsory(
110  self, key='result', data=kwargs, val=None)
111  ParseUtil.set_field_compulsory(self, key='log_obj', data=kwargs,
112  val=ALog(**log_conf) if log_conf is not None else None)
113  if hasattr(self, 'close_log') and not self.close_log and not self.abst:
114  ALog.log(obj=self, msg='Being Initialize this object', LogObject=self.log_obj)
115  ParseUtil.set_field_compulsory(
116  self, key='serializer', data=kwargs, val=serializer)
117  if not self.abst:
118  # 操作类
119  ParseUtil.set_field_compulsory(
120  self, key='operation', data=kwargs, val=ProxyOpera.DbOperation())
121  # 连接池
122  if hasattr(self, 'config_obj') and self.config_obj:
123  self.db_util = ExecuteSql.Db_opera(
124  creator=ParseUtil.fieldExist(
125  self.config_obj, 'creator', raise_exception=True),
126  POOL=None if 'POOL' not in kwargs.keys(
127  ) else kwargs['POOL'],
128  **ParseUtil.fieldExist(self.config_obj, 'kw', raise_exception=True))
129  else:
130  ALog.log_error('`config_obj` is missing', AttributeError, LogObject=self.log_obj, raise_exception=True)
131 
132  @property
133  def conversion(self):
134  """
135  将此Repository转换为ORM实体
136 
137  Return:
138  ORM转换之后的实体对象
139  """
140  return AOrm(repository=self)
141 
142  def first(self):
143  """
144  获取数据库中的第一个
145  """
146  return self.conversion.top().end()
147 
148  def last(self):
149  """
150  获取最后一个参数
151  """
152  return self.conversion.top().desc().end()
153 
154  def find_all(self, **kwargs) -> QuerySet:
155  """
156  从当前数据表格中查找所有数据
157 
158  Returns:
159  将所有结果封装成POJO对象集合并返回数据
160  """
161  # 开启任务
162  self.result = self.find_field(*self.getFields(), **kwargs)
163  return self.result
164 
165  def find_field(self, *args, **kwargs) -> QuerySet:
166  """
167  只查询指定名称的字段,如:
168 
169  SELECT user_name FROM `user`
170 
171  即可参与仅解析user_name为主的POJO对象
172 
173  :param args:需要参与解析的字段名
174 
175  :return:
176  将所有结果封装成POJO对象集合并返回数据
177 
178  """
179  # 设置名称
180  name = str(uuid.uuid1())
181  # 开启任务
182  kwargs.update(
183  {
184  'func': self.operation.__find_by_field__,
185  '__task_uuid__': name,
186  't_local': self
187  }
188  )
189 
190  result = self.operation.start(*args, **kwargs)
191 
192  self.result = self.serializer(instance=self.instance, base_data=result)
193  return self.result
194 
195  def find_one(self, sql, **kwargs):
196  """
197  查找第一条数据
198 
199  可以是一条
200 
201  也可以是很多条中的第一条
202 
203  code:
204 
205  result = self.find_many(**kwargs)
206  if len(result) == 0:
207  return None
208  else:
209  return result[0]
210 
211  :param kwargs:包含所有参数:
212 
213  pojo:参照对象
214 
215  sql:处理过并加上%s的sql语句
216 
217  params:需要填充的字段
218 
219  print_sql:是否打印sql语句
220 
221  :return 返回使用find_many()的结果种第一条
222  """
223  kwargs['sql'] = sql
224  self.result = self.find_many(**kwargs)
225  if self.result is None or len(self.result) == 0:
226  self.result = []
227  return None
228  else:
229  self.result = self.result.first()
230  return self.result
231 
232  def find_many(self, sql, **kwargs) -> QuerySet:
233  """
234  查询出多行数据
235 
236  第一个必须放置sql语句
237 
238  :param kwargs:包含所有参数:
239 
240  pojo:参照对象
241 
242  sql:处理过并加上%s的sql语句
243 
244  params:需要填充的字段
245 
246  print_sql:是否打印sql语句
247 
248  :return 将所有数据封装成POJO对象并返回
249 
250  """
251  # 设置名称
252  name = str(uuid.uuid1())
253  kwargs['sql'] = sql
254  # 开启任务
255  kwargs['func'] = self.operation.__find_many__
256  kwargs['__task_uuid__'] = name
257  kwargs['t_local'] = self
258  result = self.operation.start(**kwargs)
259 
260  self.result = self.serializer(instance=self.instance, base_data=result)
261  return self.result
262 
263  def find_sql(self, sql, **kwargs) -> QuerySet:
264  """
265 
266  返回多个数据并用list包装:
267 
268  - 可自动化操作
269 
270  - 请尽量使用find_many(sql)操作
271 
272  :param kwargs:包含所有参数:
273  sql:处理过并加上%s的sql语句
274  params:需要填充的字段
275  print_sql:是否打印sql语句
276  """
277  # kwargs['conf_obj'] = t_local.config_obj
278  # 设置名称
279  name = str(uuid.uuid1())
280  kwargs['sql'] = sql
281  # 开启任务
282  kwargs['func'] = self.operation.__find_sql__
283  kwargs['__task_uuid__'] = name
284  kwargs['t_local'] = self
285  result = self.operation.start(**kwargs)
286 
287  self.result = self.serializer(instance=self.instance, base_data=result)
288  return self.result
289 
290  def update(self, key=None):
291  """
292  执行更新操作:
293  返回受影响行数
294 
295  :param key:主键,where的参考数据
296  :return:
297  """
298  if key is None:
299  for k, v in self._fields.items():
300  if hasattr(v, "primary_key") and getattr(v, 'primary_key'):
301  key = k
302  break
303  name = str(uuid.uuid1())
304  kwargs = {
305  'pojo': self,
306  'func': self.operation.__update__,
307  '__task_uuid__': name,
308  't_local': self,
309  'key': key
310  }
311  # 开启任务
312  self.result = self.operation.start(**kwargs)
313  return self.result
314 
315  def remove(self, key=None):
316  """
317  执行更新操作:
318  返回受影响行数
319 
320  :param key:主键,where的参考数据
321  :return:
322  """
323  if key is None:
324  for k, v in self._fields.items():
325  if hasattr(v, "primary_key") and getattr(v, 'primary_key'):
326  key = k
327  break
328  name = str(uuid.uuid1())
329  kwargs = {
330  'pojo': self,
331  'func': self.operation.__remove__,
332  '__task_uuid__': name,
333  't_local': self,
334  'key': key
335  }
336  # 开启任务
337  self.result = self.operation.start(**kwargs)
338  return self.result
339 
340  def save(self, *args, **kwargs):
341  """
342  将当前储存的值存入数据库
343  """
344  kwargs['pojo'] = self
345  return self.create(*args, **kwargs)
346 
347  def create(self, pojo, **kwargs):
348  """
349  插入属性:
350  返回受影响行数
351  :param kwargs:包含所有参数:
352  pojo:参照对象
353  last_id:是否需要返回最后一行数据,默认False
354  :return:rowcount,last_id if last_id=True
355  """
356  # 设置名称
357  kwargs['pojo'] = pojo
358  name = str(uuid.uuid1())
359  # 开启任务
360  kwargs['func'] = self.operation.__insert__
361  kwargs['__task_uuid__'] = name
362  kwargs['t_local'] = self
363  self.result = self.operation.start(**kwargs)
364  return self.result
365 
366  def copy(self, **kwargs):
367  """
368  复制对象进行操做
369 
370  不建议多次创建对象,建议使用 pojo.copy()来生成对象
371  """
372  obj = copy.copy(self)
373  [setattr(obj, k, v) for k, v in kwargs.items()]
374  return obj
375 
376  def execute_sql(self, sql, params=None, mode=EX_MODEL.SELECT, **kwargs):
377  """
378  :param sql:执行的sql
379  :param params:防止sql注入的参数
380  :param mode:查询模式,默认使用SELECT,使用aestate.work.Modes.EX_MODEL枚举修改执行的sql类型
381  :param kwargs:其他需要的参数
382  """
383  kwargs['print_sql'] = True if 'print_sql' not in kwargs.keys() else kwargs['print_sql']
384  if mode is None or mode == EX_MODEL.SELECT:
385  return self.db_util.select(sql=sql, params=params, **kwargs)
386  else:
387  kwargs['last_id'] = True if 'last_id' not in kwargs.keys() else kwargs['last_id']
388  return self.db_util.insert(sql=sql, params=params, **kwargs)
389 
390  def foreign_key(self, cls, key_name, field_name=None, data=None, operation=None):
391  """
392  根据外键来查
393 
394  Examples:
395  第一种:
396 
397  >>> from apps.fontend.models import Label, SmLabel
398  >>> smlabel = SmLabel()
399  >>> label = Label()
400  >>> label.find_all()
401  >>> label.foreign_key(smlabel.copy, 'label_id')
402  >>> datas = label.datas
403 
404  第二种:
405 
406  >>> page = int(requests.GET['page']) \
407  ... if 'page' in requests.GET.keys() \
408  ... else 1
409  ...
410  >>> sm_label_list = sm_label.orm.filter(id=pk)
411  >>> sm_label.foreign_key(
412  ... cls=need.copy,
413  ... key_name='label_id',
414  ... field_name="need_list",
415  ... datas=sm_label_list,
416  ... operation=lambda dt, i: need.orm
417  ... .find()
418  ... .where(label_id=dt[i].id)
419  ... .limit((page - 1) * PAGE_SIZE, PAGE_SIZE)
420  ... .end()
421  ...)
422  >>> need_list = sm_label.datas
423  >>> return Result.success(data=need_list.to_dict())
424 
425 
426  :param cls:目标外键的类,注意不是对象,是类
427  :param key_name:外键的id
428  :param field_name:保存进去的字段名字,默认以表名命名
429  :param data:使用已有的数据作为外键
430  :param operation:自定义操作
431  """
432  child_obj = cls()
433  if field_name is None:
434  name = child_obj.get_tb_name()
435  else:
436  name = field_name
437  self.datas = self.result if data is None else data
438  for i in range(len(self.datas)):
439  if not operation:
440  data = child_obj.orm.filter(**{key_name: self.datas[i].id})
441  else:
442  data = operation(self.datas, i)
443  self.datas[i].add_field(name, data.to_dict())
aestate.work.repository.Repository.execute_sql
def execute_sql(self, sql, params=None, mode=EX_MODEL.SELECT, **kwargs)
Definition: repository.py:376
aestate.work.repository.Repository.remove
def remove(self, key=None)
Definition: repository.py:315
aestate.work.repository.Repository.find_all
QuerySet find_all(self, **kwargs)
Definition: repository.py:154
aestate.work.repository.Repository
Definition: repository.py:16
aestate.work.repository.Repository.foreign_key
def foreign_key(self, cls, key_name, field_name=None, data=None, operation=None)
Definition: repository.py:390
aestate.work.orm
Definition: orm.py:1
aestate.work.repository.Repository.find_sql
QuerySet find_sql(self, sql, **kwargs)
Definition: repository.py:263
aestate.work.repository.Repository.datas
datas
Definition: repository.py:437
aestate.work.repository.Repository.save
def save(self, *args, **kwargs)
Definition: repository.py:340
aestate.work.repository.Repository.find_one
def find_one(self, sql, **kwargs)
Definition: repository.py:195
aestate.start
def start()
Definition: __init__.py:8
aestate.work.repository.Repository.ParseUtil
ParseUtil
Definition: repository.py:83
aestate.work.Serialize
Definition: Serialize.py:1
aestate.work.repository.Repository.create
def create(self, pojo, **kwargs)
Definition: repository.py:347
aestate.util.Log
Definition: Log.py:1
aestate.work.Modes
Definition: Modes.py:1
aestate.exception
Definition: __init__.py:1
aestate.work.repository.Repository.result
result
Definition: repository.py:162
aestate.work.repository.Repository.last
def last(self)
Definition: repository.py:148
aestate.work.repository.Repository.__init__
def __init__(self, config_obj=None, instance=None, log_conf=None, close_log=False, serializer=QuerySet, **kwargs)
Definition: repository.py:23
aestate.dbs
Definition: __init__.py:1
aestate.work.sql
Definition: __init__.py:1
aestate.work.repository.Repository.find_field
QuerySet find_field(self, *args, **kwargs)
Definition: repository.py:165
aestate.work.repository.Repository.db_util
db_util
Definition: repository.py:123
aestate.work.repository.Repository.copy
def copy(self, **kwargs)
Definition: repository.py:366
aestate.work.repository.Repository.conversion
def conversion(self)
Definition: repository.py:133
aestate.work.orm.AOrm
Definition: orm.py:67
aestate.work.repository.Repository.update
def update(self, key=None)
Definition: repository.py:290
aestate.work.repository.Repository.first
def first(self)
Definition: repository.py:142
aestate.work.repository.Repository.find_many
QuerySet find_many(self, sql, **kwargs)
Definition: repository.py:232
aestate.util.Log.ALog
Definition: Log.py:122