diff --git a/README.md b/README.md
index 51f1bcfc4156be673b48b070daf232158dec7336..1d0c0e5cb35cb3de05b2fe3ea382c49e3e6e0a5f 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,17 @@
Aestate —— 多样化数据库查询
-
-
+
+
-
+
-
+
@@ -46,7 +46,7 @@ def find_all_where_id(self, id, name): ...
```xml
id,name,password,create_time,update_time
@@ -122,7 +122,7 @@ def find_all_where_id(self, id, name): ...
# 安装
-目前源代码仅开放在gitee,处于组织CACode下,仓库地址为:[aestate](https://gitee.com/cacode_cctvadmin/aestate)
+目前源代码仅开放在gitee,处于组织CACode下,仓库地址为:[aestate](https://gitee.com/aecode/aestate)
使用pip或anaconda安装aestate:
```shell
diff --git a/aestate/exception/__init__.py b/aestate/exception/__init__.py
index f8e0cc7695775df74804dd7f035777faab013d30..ddaa4ec5f5a28ad4e931fc0be2690f6a05df9726 100644
--- a/aestate/exception/__init__.py
+++ b/aestate/exception/__init__.py
@@ -1,4 +1,5 @@
import re
+import traceback
class DBException(Exception):
@@ -20,23 +21,23 @@ class FieldNotExist(AttributeError):
class SqlResultError(DBException):
- pass
+ """sql返回错误"""
class XmlParseError(Exception):
- pass
+ """xml解析错误"""
class NotFindTemplateError(XmlParseError):
- pass
+ """找不到xml模板"""
class TagAttributeError(XmlParseError):
- pass
+ """节点属性错误"""
class TagHandlerError(XmlParseError):
- pass
+ """节点处理方式错误"""
class BaseMySqlError:
@@ -47,7 +48,7 @@ class BaseMySqlError:
def ver(self):
return self.text
- def raise_exception(self):
+ def raise_exception(self, **kwargs):
ar = self.exception.args
ar_array = list(ar)
ar_array[len(ar_array) - 1] = self.text
diff --git a/aestate/opera/op_db.py b/aestate/opera/op_db.py
index 7d9b5d5bc07dd647651e9cb1d14911e8e05a8a39..632f9bef8f0bccb969b0c5d7ed24738cfe076873 100644
--- a/aestate/opera/op_db.py
+++ b/aestate/opera/op_db.py
@@ -32,8 +32,8 @@ class DbOperation(object):
kwargs.update(_kw)
_t = pool.submit(lambda x, y: func(*x, **y), args, kwargs)
# _t = threading.Thread(target=func, args=args, kwargs=kwargs, name=name)
- if not _lock.close_log:
- ALog.log(obj=_t, msg='RUNNING', task_name=name, LogObject=log_obj)
+ # if not _lock.close_log:
+ # ALog.log(obj=_t, msg='RUNNING', task_name=name, LogObject=log_obj)
result = _t.result()
# 返回结果
return result[name]
diff --git a/aestate/util/Log.py b/aestate/util/Log.py
index 6771bac51fb802aa4ae42e9dd5de0f52af6a64ef..69378e3502df43a96eb7ef7b15accb61637e0e30 100644
--- a/aestate/util/Log.py
+++ b/aestate/util/Log.py
@@ -5,7 +5,7 @@ import threading
from aestate.work.Modes import Singleton
from aestate.exception import e_fields
from aestate.util import others
-from aestate.work.commad import __logo__
+from aestate.work.commad import __log_logo__
class FieldsLength:
@@ -113,15 +113,17 @@ class ConsoleWrite:
return out
-def write(path, content, max_size):
+def write(path, *content):
"""
写出文件
:param path:位置
:param content:内容
- :param max_size:文件保存的最大限制
:return:
"""
- _sep_path = path.split(os.sep)
+ # 防止有些使用`/`有些用`\\`
+ _sep_path = []
+ s = path.split('/')
+ [_sep_path.extend(item.split('\\')) for item in s]
_path = ''
for i in _sep_path:
_end = _sep_path[len(_sep_path) - 1]
@@ -132,16 +134,23 @@ def write(path, content, max_size):
if not os.path.exists(_path):
if '.' not in i:
os.makedirs(_path)
-
- content += '\n'
+ temp = []
+
+ if isinstance(content, str):
+ temp.append(content)
+ elif isinstance(content, tuple):
+ for c in content:
+ if isinstance(c, tuple):
+ temp.extend(c)
+ else:
+ temp.append(str(c))
+ else:
+ temp.append(str(content))
+ temp.append('\n')
+ _write_content = ''.join([str(_) for _ in temp])
with open(os.path.join(_path), mode="a", encoding="UTF-8") as f:
- f.write(content)
+ f.write(_write_content)
f.close()
- _size = os.path.getsize(_path)
- if _size >= max_size:
- os.remove(_path)
- # 递归
- write(path, content, max_size)
class ALog(object):
@@ -161,7 +170,6 @@ class ALog(object):
:param max_clear:日志储存最大限制,默认10MB 单位:MB
"""
- # bug
self.max_clear = max_clear * 1024 * 1000
self.path = path
self.print_flag = print_flag
@@ -169,6 +177,10 @@ class ALog(object):
self.__info_logo_show__ = False
self.__warn_logo_show__ = False
self.__error_logo_show__ = False
+ # 文件名,当满足最大时将会使用一个新的文件作为储存日志
+ self.__info_file_name = []
+ self.__warn_file_name = []
+ self.__error_file_name = []
@staticmethod
def pure_log(msg, **kwargs):
@@ -210,7 +222,7 @@ class ALog(object):
# write_repr = repr if repr and not repr_c else repr_c[0] if repr_c else type(obj)
# 格式:时间 类型 日志名称 对象地址 被调用行号 执行类型 信息
- con_text = ' '.join([str(t), str(field), str(line), str(hex(id(obj))),
+ con_text = ' '.join([str(t), str(field.value), str(line), str(hex(id(obj))),
'[{}]'.format(task_name), str(write_repr), f" : {msg}"])
t = ConsoleWrite.format_color(f"{t}".ljust(FieldsLength.DATETIME_FORMAT), ConsoleColor.FontColor.CYAN)
@@ -228,42 +240,38 @@ class ALog(object):
write_repr = ConsoleWrite.format_color(write_repr, ConsoleColor.FontColor.LIGHT_GREEN)
msg = f" : {msg}"
- info = "{}{}{}{}{}{}{}".format(t, field, line, hex_id, ' [{}] '.format(task_name), write_repr, msg)
+ info = "{}{}{}{}{}{}{}".format(t, _field, line, hex_id, ' [{}] '.format(task_name), write_repr, msg)
print(info)
- if LogObject is not None:
- _path = "%s%s%s%s" % (os.sep, str(field.value).lower(), os.sep, 'log.log')
- logo_show = False
- if field == e_fields.LogStatus.Info:
- logo_show = LogObject.__info_logo_show__
- elif field == e_fields.LogStatus.Error:
- logo_show = LogObject.__error_logo_show__
- elif field == e_fields.LogStatus.Warn:
- logo_show = LogObject.__warn_logo_show__
- if not logo_show:
+
+ def __log_obj_write__():
+ if LogObject is not None:
if field == e_fields.LogStatus.Info:
- LogObject.__info_logo_show__ = True
+ LogObject.info(con_text)
elif field == e_fields.LogStatus.Error:
- LogObject.__error_logo_show__ = True
+ LogObject.error(con_text)
elif field == e_fields.LogStatus.Warn:
- LogObject.__warn_logo_show__ = True
- else:
- LogObject.__info_logo_show__ = True
- LogObject.log_util(_path, __logo__)
- LogObject.log_util(_path, con_text)
+ LogObject.warn(con_text)
+ if obj is not None:
+ if hasattr(obj, 'log_obj'):
+ if field == e_fields.LogStatus.Info:
+ obj.log_obj.info(con_text)
+ elif field == e_fields.LogStatus.Error:
+ obj.log_obj.error(con_text)
+ elif field == e_fields.LogStatus.Warn:
+ obj.log_obj.warn(con_text)
+ else:
+ __log_obj_write__()
+ else:
+ __log_obj_write__()
if func is not None:
func(con_text)
return info
@staticmethod
- def warning(msg, obj=None, line=sys._getframe().f_back.f_lineno, task_name='WARNING', LogObject=None):
-
- consoleWrite = ConsoleWrite()
- consoleWrite.fontColor = ConsoleColor.FontColor.WARNING_COLOR
-
- ALog.log(msg=msg, obj=obj, line=line, task_name=task_name, LogObject=LogObject, field=e_fields.LogStatus.Warn,
- func=LogObject)
+ def warning(**kwargs):
+ ALog.log(task_name='WARNING', field=e_fields.LogStatus.Warn, **kwargs)
@staticmethod
def log_error(msg, obj=None, line=sys._getframe().f_back.f_lineno, task_name='ERROR', LogObject=None,
@@ -288,39 +296,75 @@ class ALog(object):
LogObject.error(msg)
raise cls(msg)
- def success(self, content):
+ def get_filename(self, status):
+
+ def _r(s, x):
+ _path = os.path.join(self.path, s)
+ if len(x) == 0:
+ x.append(others.date_format(fmt='%Y.%m.%d.%H.%M.%S') + '.log')
+ else:
+ if not os.path.exists(os.path.join(_path, x[len(x) - 1])):
+ write(os.path.join(_path, 'temp.temp'), '')
+ if os.path.getsize(os.path.join(_path, x[len(x) - 1])) >= self.max_clear:
+ x.append(others.date_format(fmt='%Y.%m.%d.%H.%M.%S') + '.log')
+ return x[len(x) - 1]
+
+ if status == e_fields.LogStatus.Info:
+ center_name = 'info'
+ oa = self.__info_file_name
+ elif status == e_fields.LogStatus.Error:
+ center_name = 'error'
+ oa = self.__warn_file_name
+ elif status == e_fields.LogStatus.Warn:
+ center_name = 'warn'
+ oa = self.__error_file_name
+ else:
+ center_name = 'info'
+ oa = self.__info_file_name
+ return os.path.join(center_name, _r(center_name, oa))
+
+ def info(self, *content, **kwargs):
"""
成功日志
:param content:内容
:return:
"""
- _path = "%s%s%s%s" % (os.sep, 'success', os.sep, 'log.log')
+ _path = self.get_filename(e_fields.LogStatus.Info)
+ # _path = "%s%s%s%s" % (os.sep, 'info', os.sep, filename)
if not self.__info_logo_show__:
self.__info_logo_show__ = True
- self.log_util(_path, __logo__)
- self.log_util(_path, content)
+ self.log_util(_path, __log_logo__, **kwargs)
+ self.log_util(_path, content, **kwargs)
- def error(self, content):
+ def error(self, *content, **kwargs):
"""
错误日志
:param content:内容
:return:
"""
- _path = "%s%s%s%s" % (os.sep, 'error', os.sep, 'log.log')
- self.log_util(_path, content)
-
- def warn(self, content):
+ _path = self.get_filename(e_fields.LogStatus.Error)
+ # _path = "%s%s%s%s" % (os.sep, 'error', os.sep, filename)
+ if not self.__warn_logo_show__:
+ self.__warn_logo_show__ = True
+ self.log_util(_path, __log_logo__, **kwargs)
+ self.log_util(_path, content, **kwargs)
+
+ def warn(self, *content, **kwargs):
"""
警告日志
:param content:内容
:return:
"""
- _path = "%s%s%s%s" % (os.sep, 'warn', os.sep, 'log.log')
- self.log_util(_path, content)
-
- def log_util(self, path_str, content):
+ _path = self.get_filename(e_fields.LogStatus.Warn)
+ # _path = "%s%s%s%s" % (os.sep, 'warn', os.sep, filename)
+ if not self.__error_logo_show__:
+ self.__error_logo_show__ = True
+ self.log_util(_path, __log_logo__, **kwargs)
+ self.log_util(_path, content, **kwargs)
+
+ def log_util(self, path_str, *content, **kwargs):
"""
- 日志工具,勿用
+ 日志工具
:param path_str:
:param content:
:return:
@@ -328,10 +372,10 @@ class ALog(object):
path = self.get_path(path_str)
_date = others.date_format()
# _log = '[%s]\t[%s] - %s\r\n' % (_date, 'content', str(content))
- if self.print_flag:
- self.log(content)
+ if '_print' in kwargs.keys() and kwargs['_print']:
+ print(content)
if self.save_flag:
- write(path, content, self.max_clear)
+ write(path, *content)
def get_path(self, end_path):
"""
@@ -345,3 +389,10 @@ class ALog(object):
def __new__(cls, *args, **kwargs):
instance = Singleton.createDbOpera(cls)
return instance
+
+
+class logging(object):
+
+ @classmethod
+ def gen(cls, _object) -> ALog:
+ return _object.log_obj
diff --git a/aestate/util/others.py b/aestate/util/others.py
index 6f96c14d0a5edca63415e40f067c28148f930b73..8f1b165a7ed628d20df3a964c221987f1a2e15c3 100644
--- a/aestate/util/others.py
+++ b/aestate/util/others.py
@@ -16,7 +16,7 @@ def conversion_types(val):
return val
-def date_format(time_obj=time, fmt='%Y-%m-%d %H:%M:%S'):
+def date_format(time_obj=time, fmt='%Y-%m-%d %H:%M:%S') -> str:
"""
时间转字符串
:param time_obj:
diff --git a/aestate/work/Manage.py b/aestate/work/Manage.py
index 5f495fe65c5d6c59e14fd106a7f6a2b230caa7fc..868ff04974fa9ec3bc37ef6e8fe9b5bc76169c1d 100644
--- a/aestate/work/Manage.py
+++ b/aestate/work/Manage.py
@@ -4,7 +4,7 @@ from aestate.util import others
from aestate.work.Cache import PojoManage
from aestate.work.Serialize import QuerySet
-from aestate.work.orm import CACodePureORM
+from aestate.work.orm import AOrm
from aestate.dbs._mysql import tag
from aestate.work import repository
from aestate.work import Banner
@@ -119,7 +119,7 @@ class Pojo(repository.Repository):
"""
转ORM框架
"""
- return CACodePureORM(repository=self)
+ return AOrm(repository=self)
def format(self, key, name):
"""
@@ -133,11 +133,6 @@ class Pojo(repository.Repository):
self._fields['ig'] = []
self.format(key, name)
- def __str__(self):
- """
- """
- return ''
-
def get_tb_name(self):
"""
获取当前pojo的表名
diff --git a/aestate/work/commad.py b/aestate/work/commad.py
index f76b7854ff5c58e2e3ed90e5a2845b33c39834e7..ea70a8ed64fcdfca2540557de01cf2ef042a20d3 100644
--- a/aestate/work/commad.py
+++ b/aestate/work/commad.py
@@ -3,7 +3,7 @@
# @Time: 2021/6/27 20:47
# @Author: CACode
# 版本有三种状态 正式版从1.0.0往后逐个加 1,对应版本的补丁为'a+补丁次数'
-__version__ = '1.0.4a1'
+__version__ = '1.0.4a2'
__description__ = "Aestate framework for Python,You can see:https://gitee.com/cacode_cctvadmin/aestate"
__author__ = "CACode"
__author_email__ = "cacode@163.com"
@@ -20,6 +20,16 @@ __logo__ = """
========\_\=/_/====\_\___||___/\__\__,_|\__\___|=/_/========
""" % __version__
+__log_logo__ = """
+ :: Aestate Framework :: (version:%s)
+ + __ _ _ __ +
+ + / / /\ | | | | \ \ +
+ + / / / \ ___ ___| |_ __ _| |_ ___ \ \ +
+ + | | / /\ \ / _ \/ __| __/ _` | __/ _ \ | | +
+ + \ \ / ____ \ __/\__ \ || (_| | || __/ / / +
+========\_\=/_/====\_\___||___/\__\__,_|\__\___|=/_/========
+""" % __version__
+
import importlib
try:
diff --git a/aestate/work/orm.py b/aestate/work/orm.py
index 1199bdc0b23e6c8e6090c14bc0782650925c3733..8a2cc01b48199afb91c6f4d79fc209e1af5e2eb4 100644
--- a/aestate/work/orm.py
+++ b/aestate/work/orm.py
@@ -1,3 +1,4 @@
+from enum import Enum
from typing import List
from aestate.exception import e_fields, SqlResultError
@@ -60,7 +61,7 @@ class BaseCover:
return res
-class CACodePureORM(object):
+class AOrm(object):
"""
纯净的ORM模式:
你可以使用find('table').by('args').order_by('args').desc().end()方式执行sql
@@ -71,6 +72,10 @@ class CACodePureORM(object):
上手快
"""
+ class Mode(Enum):
+ FIND = 0
+ INSERT = 1
+
def __init__(self, repository):
"""
初始化ORM
@@ -80,6 +85,7 @@ class CACodePureORM(object):
:param repository:仓库
s """
+ self.exmode = None
self.args = []
self.params = []
self.sqlFields = None
@@ -124,6 +130,7 @@ s """
更新:
如果args字段长度为0,默认为查找全部
"""
+ self.exmode = AOrm.Mode.FIND
self.args.append(self.sqlFields.find_str)
# 如果有as字段
alias = None
@@ -373,12 +380,13 @@ s """
sql += ''.join(self.args)
if need_sql:
return sql
- if self.sqlFields.find_str in sql:
+ if self.exmode == AOrm.Mode.FIND:
self._result = self.repository.db_util.select(
sql=sql,
params=self.params,
print_sql=print_sql,
- last_id=last_id
+ last_id=last_id,
+ **self.repository.__dict__
)
_result_objs = []
for i in self._result:
diff --git a/aestate/work/repository.py b/aestate/work/repository.py
index fd653251353691b18a2ae614a458c3e75b49328b..cc10eee53aaedacf2d9978bee924e43d2f36a8fa 100644
--- a/aestate/work/repository.py
+++ b/aestate/work/repository.py
@@ -7,7 +7,7 @@ from aestate.dbs import _mysql
from aestate.opera import op_db, global_db
from aestate.util.Log import ALog
-from aestate.work.orm import CACodePureORM
+from aestate.work.orm import AOrm
# 每个任务唯一ID
import uuid
@@ -90,8 +90,6 @@ class Repository:
# 当本类为抽象类时,仅设置所需要的值
ParseUtil.set_field_compulsory(
self, key='close_log', data=kwargs, val=close_log)
- if hasattr(self, 'close_log') and not self.close_log and not self.abst:
- ALog.warning(obj=self, msg='Being Initialize this object')
# 有没有表名
ParseUtil.set_field_compulsory(self, key='__table_name__', data=kwargs,
val=self.__table_name__ if hasattr(self, '__table_name__') else
@@ -112,6 +110,8 @@ class Repository:
self, key='result', data=kwargs, val=None)
ParseUtil.set_field_compulsory(self, key='log_obj', data=kwargs,
val=ALog(**log_conf) if log_conf is not None else None)
+ if hasattr(self, 'close_log') and not self.close_log and not self.abst:
+ ALog.log(obj=self, msg='Being Initialize this object', LogObject=self.log_obj)
ParseUtil.set_field_compulsory(
self, key='serializer', data=kwargs, val=serializer)
if not self.abst:
@@ -138,7 +138,7 @@ class Repository:
Return:
ORM转换之后的实体对象
"""
- return CACodePureORM(repository=self)
+ return AOrm(repository=self)
def first(self):
"""
diff --git a/example/db_base.py b/example/db_base.py
index c12db10839ebb10864e0be40d0eec2fd555dd8ea..93073248577d480cdccf109299168f96f3daa805 100644
--- a/example/db_base.py
+++ b/example/db_base.py
@@ -64,7 +64,7 @@ class table_template(Pojo):
# 是否允许保存日志
'save_flag': True,
# 当日志到达多少MB时删除日志重新记录
- 'max_clear': 100
+ 'max_clear': 10
},
# 必备的字段,每一个Pojo对象都必须包含一个`**kwargs`
**kwargs)
diff --git a/example/operas/logtest/__init__.py b/example/operas/logtest/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fda586759c924332efe231476fb3e2e834a49a78
--- /dev/null
+++ b/example/operas/logtest/__init__.py
@@ -0,0 +1 @@
+# -*- utf-8 -*-
diff --git a/example/operas/logtest/t1.py b/example/operas/logtest/t1.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b84dbb86785bfbb8d4bc0505ef03de56f6a9e84
--- /dev/null
+++ b/example/operas/logtest/t1.py
@@ -0,0 +1,8 @@
+# -*- utf-8 -*-
+from aestate.util.Log import logging
+from example.table.demoModels import Demo
+
+log = logging.gen(Demo())
+[log.info(True, 'test info') for _ in range(10000)]
+[log.warn(True, 'test warn') for _ in range(10000)]
+[log.error(True, 'test error') for _ in range(10000)]
diff --git a/example/operas/mysql/basis/find.py b/example/operas/mysql/basis/find.py
index 5a6ef7171e2d84ad35a8c1b4192fb8b68a980cd5..bf89a026869800b4b24538f8d536088b60713f6e 100644
--- a/example/operas/mysql/basis/find.py
+++ b/example/operas/mysql/basis/find.py
@@ -1,7 +1,9 @@
+from aestate.util.Log import logging
from example.table.demoModels import Demo
import pandas
demo = Demo()
+log = logging.gen(demo)
r1 = demo.find_all(print_sql=False)
r1[0].name = "aaaaa"
r1[0].update()
@@ -10,12 +12,12 @@ r3 = demo.find_field("id", "name", "password")
r4 = demo.find_one("SELECT * FROM demo WHERE id=%s", params=[1])
r5 = demo.find_sql("SELECT * FROM demo WHERE id>%s", params=[0])
r6 = demo.orm.find().where(name__love='a').end()
-print('r1', type(r1), r1)
-print('r2', type(r2), r2)
-print('r3', type(r3), r3)
-print('r4', type(r4), r4)
-print('r5', type(r5), r5)
-print('r6', type(r6), r6)
+log.error(True, 'r1', type(r1), r1)
+log.error(True, 'r2', type(r2), r2)
+log.error(True, 'r3', type(r3), r3)
+log.error(True, 'r4', type(r4), r4)
+log.error(True, 'r5', type(r5), r5)
+log.error(True, 'r6', type(r6), r6)
df = pandas.DataFrame.from_dict(r1.to_dict())
print(df)