Browse Source

perf: 优化CamelCaseUtil和SnakeCaseUtil以兼容更多转换场景

master
insistence 4 months ago
parent
commit
bb143ac15a
  1. 127
      ruoyi-fastapi-backend/utils/common_util.py

127
ruoyi-fastapi-backend/utils/common_util.py

@ -7,7 +7,8 @@ from openpyxl.styles import Alignment, PatternFill
from openpyxl.utils import get_column_letter from openpyxl.utils import get_column_letter
from openpyxl.worksheet.datavalidation import DataValidation from openpyxl.worksheet.datavalidation import DataValidation
from sqlalchemy.engine.row import Row from sqlalchemy.engine.row import Row
from typing import List from typing import Any, Dict, List, Literal, Union
from config.database import Base
from config.env import CachePathConfig from config.env import CachePathConfig
@ -38,13 +39,71 @@ def worship():
""") """)
class SqlalchemyUtil:
"""
sqlalchemy工具类
"""
@classmethod
def base_to_dict(
cls, obj: Union[Base, Dict], transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
):
"""
将sqlalchemy模型对象转换为字典
:param obj: sqlalchemy模型对象或普通字典
:param transform_case: 转换得到的结果形式可选的有'no_case'(不转换)'snake_to_camel'(下划线转小驼峰)'camel_to_snake'(小驼峰转下划线)默认为'no_case'
:return: 字典结果
"""
if isinstance(obj, Base):
base_dict = obj.__dict__.copy()
base_dict.pop('_sa_instance_state', None)
elif isinstance(obj, dict):
base_dict = obj.copy()
if transform_case == 'snake_to_camel':
return {CamelCaseUtil.snake_to_camel(k): v for k, v in base_dict.items()}
elif transform_case == 'camel_to_snake':
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in base_dict.items()}
return base_dict
@classmethod
def serialize_result(
cls, result: Any, transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
):
"""
将sqlalchemy查询结果序列化
:param result: sqlalchemy查询结果
:param transform_case: 转换得到的结果形式可选的有'no_case'(不转换)'snake_to_camel'(下划线转小驼峰)'camel_to_snake'(小驼峰转下划线)默认为'no_case'
:return: 序列化结果
"""
if isinstance(result, (Base, dict)):
return cls.base_to_dict(result, transform_case)
elif isinstance(result, list):
return [cls.serialize_result(row, transform_case) for row in result]
elif isinstance(result, Row):
if all([isinstance(row, Base) for row in result]):
return [cls.base_to_dict(row, transform_case) for row in result]
elif any([isinstance(row, Base) for row in result]):
return [cls.serialize_result(row, transform_case) for row in result]
else:
result_dict = result._asdict()
if transform_case == 'snake_to_camel':
return {CamelCaseUtil.snake_to_camel(k): v for k, v in result_dict.items()}
elif transform_case == 'camel_to_snake':
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in result_dict.items()}
return result_dict
return result
class CamelCaseUtil: class CamelCaseUtil:
""" """
下划线形式(snake_case)转小驼峰形式(camelCase)工具方法 下划线形式(snake_case)转小驼峰形式(camelCase)工具方法
""" """
@classmethod @classmethod
def snake_to_camel(cls, snake_str): def snake_to_camel(cls, snake_str: str):
""" """
下划线形式字符串(snake_case)转换为小驼峰形式字符串(camelCase) 下划线形式字符串(snake_case)转换为小驼峰形式字符串(camelCase)
@ -57,41 +116,14 @@ class CamelCaseUtil:
return words[0] + ''.join(word.capitalize() for word in words[1:]) return words[0] + ''.join(word.capitalize() for word in words[1:])
@classmethod @classmethod
def transform_result(cls, result): def transform_result(cls, result: Any):
""" """
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法 针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
:param result: 输入数据 :param result: 输入数据
:return: 小驼峰形式结果 :return: 小驼峰形式结果
""" """
if result is None: return SqlalchemyUtil.serialize_result(result=result, transform_case='snake_to_camel')
return result
# 如果是字典,直接转换键
elif isinstance(result, dict):
return {cls.snake_to_camel(k): v for k, v in result.items()}
# 如果是一组字典或其他类型的列表,遍历列表进行转换
elif isinstance(result, list):
return [
cls.transform_result(row)
if isinstance(row, (dict, Row))
else (
cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row
)
for row in result
]
# 如果是sqlalchemy的Row实例,遍历Row进行转换
elif isinstance(result, Row):
return [
cls.transform_result(row)
if isinstance(row, dict)
else (
cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row
)
for row in result
]
# 如果是其他类型,如模型实例,先转换为字典
else:
return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns})
class SnakeCaseUtil: class SnakeCaseUtil:
@ -100,7 +132,7 @@ class SnakeCaseUtil:
""" """
@classmethod @classmethod
def camel_to_snake(cls, camel_str): def camel_to_snake(cls, camel_str: str):
""" """
小驼峰形式字符串(camelCase)转换为下划线形式字符串(snake_case) 小驼峰形式字符串(camelCase)转换为下划线形式字符串(snake_case)
@ -112,41 +144,14 @@ class SnakeCaseUtil:
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', words).lower() return re.sub('([a-z0-9])([A-Z])', r'\1_\2', words).lower()
@classmethod @classmethod
def transform_result(cls, result): def transform_result(cls, result: Any):
""" """
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法 针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
:param result: 输入数据 :param result: 输入数据
:return: 小驼峰形式结果 :return: 小驼峰形式结果
""" """
if result is None: return SqlalchemyUtil.serialize_result(result=result, transform_case='camel_to_snake')
return result
# 如果是字典,直接转换键
elif isinstance(result, dict):
return {cls.camel_to_snake(k): v for k, v in result.items()}
# 如果是一组字典或其他类型的列表,遍历列表进行转换
elif isinstance(result, list):
return [
cls.transform_result(row)
if isinstance(row, (dict, Row))
else (
cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row
)
for row in result
]
# 如果是sqlalchemy的Row实例,遍历Row进行转换
elif isinstance(result, Row):
return [
cls.transform_result(row)
if isinstance(row, dict)
else (
cls.transform_result({c.name: getattr(row, c.name) for c in row.__table__.columns}) if row else row
)
for row in result
]
# 如果是其他类型,如模型实例,先转换为字典
else:
return cls.transform_result({c.name: getattr(result, c.name) for c in result.__table__.columns})
def bytes2human(n, format_str='%(value).1f%(symbol)s'): def bytes2human(n, format_str='%(value).1f%(symbol)s'):

Loading…
Cancel
Save