refactor(代码生成): 移除驼峰命名转换并优化模板变量命名

重构代码生成模块,移除不必要的驼峰命名转换逻辑,统一使用下划线命名风格
优化模板上下文变量命名,使其更加清晰和一致
修复SQL查询参数处理和表创建逻辑
简化模型转换逻辑,直接使用Pydantic的model_validate方法
更新.gitignore文件,添加前端环境变量配置
This commit is contained in:
zhangtao
2025-10-17 02:17:56 +08:00
parent 2186566a0e
commit 0ea88c3320
14 changed files with 551 additions and 613 deletions
@@ -93,20 +93,17 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
:param search: 查询参数对象
:return: 代码生成业务表列表信息对象
"""
# 构建查询条件
query = select(GenTableModel).options(selectinload(GenTableModel.columns))
if search:
# 手动构建查询条件
if search.table_name and search.table_name[1]: # ('like', value)
query = query.where(GenTableModel.table_name.like(f"%{search.table_name[1]}%"))
if search.table_comment and search.table_comment[1]: # ('like', value)
query = query.where(GenTableModel.table_comment.like(f"%{search.table_comment[1]}%"))
query = query.order_by(GenTableModel.created_at.desc()).distinct()
# 获取所有数据
result = await self.db.execute(query)
result = await self.db.execute(
select(GenTableModel)
.options(selectinload(GenTableModel.columns))
.where(
GenTableModel.table_name.like(f"%{search.table_name}%") if search and search.table_name else GenTableModel.id.isnot(None),
GenTableModel.table_comment.like(f"%{search.table_comment}%") if search and search.table_comment else GenTableModel.id.isnot(None),
)
.order_by(GenTableModel.created_at.desc())
.distinct()
)
gen_table_all = result.scalars().all()
return gen_table_all
@@ -141,7 +138,8 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
删除
"""
await self.db.execute(
delete(GenTableModel).where(GenTableModel.id.in_(ids))
delete(GenTableModel)
.where(GenTableModel.id.in_(ids))
)
await self.db.flush()
@@ -189,7 +187,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
else:
query_sql = (
select(
text("'' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("'fastapiadmin' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("name as table_name"),
text("type as table_type"),
text("name as table_comment"), # SQLite中使用name作为表名和注释
@@ -204,7 +202,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
# 动态条件构造
params = {}
if search and search.table_name and search.table_name[1]:
if search and search.table_name:
if settings.DATABASE_TYPE == "sqlite":
query_sql = query_sql.where(
text("lower(name) like lower(:table_name)")
@@ -213,8 +211,8 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
query_sql = query_sql.where(
text("lower(table_name) like lower(:table_name)")
)
params['table_name'] = f"%{search.table_name[1]}%"
if search and search.table_comment and search.table_comment[1]:
params['table_name'] = f"%{search.table_name}%"
if search and search.table_comment:
if settings.DATABASE_TYPE == "sqlite":
query_sql = query_sql.where(
text("lower(name) like lower(:table_comment)")
@@ -223,7 +221,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
query_sql = query_sql.where(
text("lower(table_comment) like lower(:table_comment)")
)
params['table_comment'] = f"%{search.table_comment[1]}%"
params['table_comment'] = f"%{search.table_comment}%"
# 执行查询并绑定参数
all_data = (await self.db.execute(query_sql, params)).fetchall()
@@ -284,7 +282,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
else:
query_sql = (
select(
text("'' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("'fastapiadmin' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("name as table_name"),
text("type as table_type"),
text("name as table_comment"), # SQLite中使用name作为表名和注释
@@ -297,11 +295,11 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
)
)
table_names_str = "','".join(table_names)
# 修复SQL查询中的参数绑定问题
if table_names:
if settings.DATABASE_TYPE == "sqlite":
# 对于SQLite,我们直接在SQL中使用表名,因为参数绑定有问题
table_names_str = "','".join(table_names)
query_sql = query_sql.where(
text(f"name IN ('{table_names_str}')")
)
@@ -309,7 +307,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
else:
# MySQL和PostgreSQL使用:table_names占位符
query_sql = query_sql.where(
text("table_name IN :table_names")
text(f"table_name IN ('{table_names_str}')")
)
# 使用params方法正确绑定参数
query_sql = query_sql.params(table_names=tuple(table_names))
@@ -330,25 +328,25 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
dict_data.append(dict_row)
return dict_data
async def create_table_by_sql(self, sql_statements: List[Expression | None]) -> None:
async def create_table_by_sql(self, sql: str) -> bool:
"""
根据sql语句创建表结构
:param db: orm对象
:param sql_statements: sql语句的ast列表
:param sql: sql语句
:return:
"""
try:
for sql_statement in sql_statements:
# 检查sql_statement是否为空
if not sql_statement:
continue
sql = sql_statement.sql(dialect=settings.DATABASE_TYPE)
await self.db.execute(text(sql))
await self.db.execute(text(sql))
# 提交事务
await self.db.commit()
await self.db.flush()
return True
except Exception as e:
# 如果发生异常,回滚事务
await self.db.rollback()
logger.error(f"创建表时发生错误: {e}")
return False
class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, GenTableColumnSchema]):
@@ -358,10 +356,18 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
"""初始化CRUD"""
super().__init__(model=GenTableColumnModel, auth=auth)
async def get_gen_table_column_by_id(self, id: int) -> Optional[GenTableColumnModel]:
"""根据业务表字段ID获取业务表字段信息"""
return await self.get(id=id)
async def get_gen_table_column_list_by_table_id(self, table_id: int) -> Optional[GenTableColumnModel]:
"""根据业务表ID获取业务表字段列表信息"""
return await self.get(table_id=table_id)
async def list_gen_table_column_crud_by_table_id(self, table_id: int, order_by: Optional[List[Dict[str, str]]] = None) -> Sequence[GenTableColumnModel]:
"""根据业务表ID查询业务表字段列表"""
return await self.list(search={"table_id": table_id}, order_by=order_by)
async def get_gen_db_table_columns_by_name(self, table_name: str | None) -> List[GenTableColumnOutSchema]:
"""
根据业务表名称获取业务表字段列表信息
@@ -421,28 +427,23 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
FROM
pragma_table_info(:table_name)
"""
query = text(query_sql).bindparams(table_name=table_name)
gen_db_table_columns_raw = (
rows = (
await self.db.execute(query)
).fetchall()
result = []
for row in gen_db_table_columns_raw:
# 构造字段信息字典
column_dict = {
"column_name": row[0],
"is_required": row[1],
"is_pk": row[2],
"sort": row[3],
"column_comment": row[4],
"is_increment": row[5],
"column_type": row[6]
}
# 创建GenTableColumnOutSchema对象
column_schema = GenTableColumnOutSchema(**column_dict)
result.append(column_schema)
result = [
GenTableColumnOutSchema(
column_name=row[0],
is_required=row[1],
is_pk=row[2],
sort=row[3],
column_comment=row[4],
is_increment=row[5],
column_type=row[6]
)
for row in rows
]
return result
@@ -15,8 +15,8 @@ class GenTableQueryParam:
table_comment: Optional[str] = Query(None, description="表注释"),
) -> None:
# 模糊查询字段
self.table_name = ("like", table_name)
self.table_comment = ("like", table_comment)
self.table_name = table_name
self.table_comment = table_comment
class GenTableColumnQueryParam:
@@ -2,13 +2,12 @@
from typing import List, Literal, Optional
from pydantic import BaseModel, ConfigDict, Field, model_validator
from pydantic.alias_generators import to_camel
from app.common.constant import GenConstant
from app.core.base_schema import BaseSchema
class GenTableOptionModel(BaseModel):
class GenTableOptionSchema(BaseModel):
model_config = ConfigDict(from_attributes=True)
@@ -52,7 +51,7 @@ class GenTableBaseSchema(BaseModel):
options: Optional[str] = Field(default=None, description='其它生成选项')
description: Optional[str] = Field(default=None, description='功能描述')
params: Optional[GenTableOptionModel] = Field(default=None, description='前端传递过来的表附加信息,转换成json字符串后放到options')
params: Optional[GenTableOptionSchema] = Field(default=None, description='前端传递过来的表附加信息,转换成json字符串后放到options')
class GenTableSchema(GenTableBaseSchema):
@@ -112,14 +111,14 @@ class GenTableColumnSchema(BaseModel):
"""
代码生成业务表字段创建模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
model_config = ConfigDict(from_attributes=True)
table_id: Optional[int] = Field(default=None, description='归属表编号')
column_name: Optional[str] = Field(default=None, description='列名称')
column_comment: Optional[str] = Field(default=None, description='列描述')
column_type: Optional[str] = Field(default=None, description='列类型')
python_type: Optional[str] = Field(default=None, description='PYTHON类型')
python_field: Optional[str] = Field(default=None, description='PYTHON字段名')
python_type: Optional[str] = Field(default=None, description='python类型')
python_field: Optional[str] = Field(default=None, description='python字段名')
is_pk: Optional[str] = Field(default=None, description='是否主键(1是)')
is_increment: Optional[str] = Field(default=None, description='是否自增(1是)')
is_required: Optional[str] = Field(default=None, description='是否必填(1是)')
@@ -8,15 +8,15 @@ from typing import Any, List, Dict, Literal, Optional
from sqlglot.expressions import Add, Alter, Create, Delete, Drop, Expression, Insert, Table, TruncateTable, Update
from sqlglot import parse as sqlglot_parse
from app.api.v1.module_generator.gencode.model import GenTableModel
from app.config.setting import settings
from app.core.exceptions import CustomException
from app.common.constant import GenConstant
from app.common.response import SuccessResponse
from app.api.v1.module_system.auth.schema import AuthSchema
from app.utils.common_util import CamelCaseUtil
from app.utils.gen_util import GenUtils
from app.utils.jinja2_template_util import Jinja2TemplateInitializerUtil, Jinja2TemplateUtil
from .schema import GenTableSchema, GenTableOutSchema, GenTableOutSchema, GenTableColumnSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
from .schema import GenTableOptionSchema, GenTableSchema, GenTableOutSchema, GenTableOutSchema, GenTableColumnSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
from .param import GenTableQueryParam
from .crud import GenTableColumnCRUD, GenTableCRUD
@@ -34,6 +34,10 @@ class GenTableService:
gen_table = await cls.get_gen_table_by_id_service(auth, table_id)
gen_tables = await cls.get_gen_table_all_service(auth)
gen_columns = await GenTableColumnService.get_gen_table_column_list_by_table_id_service(auth, table_id)
if gen_table.options:
table_options = GenTableOptionSchema(**json.loads(gen_table.options))
gen_table.parent_menu_id = table_options.parent_menu_id
gen_table.columns = gen_columns
return dict(info=gen_table, rows=gen_columns, tables=gen_tables)
@classmethod
@@ -55,23 +59,17 @@ class GenTableService:
async def get_gen_db_table_list_by_name_service(cls, auth: AuthSchema, table_names: List[str]) -> List[GenTableOutSchema]:
"""根据表名称组获取数据库列表信息"""
gen_db_table_list_result = await GenTableCRUD(auth=auth).get_db_table_list_by_names(table_names)
# 修复:将GenDBTableSchema对象转换为字典后再传递给GenTableOutSchema
result = []
for gen_table in CamelCaseUtil.transform_result(gen_db_table_list_result):
# 确保gen_table是字典类型
if hasattr(gen_table, 'model_dump'):
gen_table_dict = gen_table.model_dump()
elif isinstance(gen_table, dict):
gen_table_dict = gen_table
else:
gen_table_dict = gen_table.__dict__
result.append(GenTableOutSchema(**gen_table_dict))
# 检查是否有未找到的表
found_table_names = [table.table_name for table in result]
found_table_names = [table.table_name for table in gen_db_table_list_result]
missing_tables = [name for name in table_names if name not in found_table_names]
if missing_tables:
raise CustomException(msg=f"以下数据表不存在: {', '.join(missing_tables)}")
# 修复:将GenDBTableSchema对象转换为字典后再传递给GenTableOutSchema
result = []
for gen_table in gen_db_table_list_result:
result.append(GenTableOutSchema(**gen_table.model_dump()))
return result
@@ -141,7 +139,7 @@ class GenTableService:
raise CustomException(msg='sql语句不是合法的建表语句')
table_names = cls.__get_table_names(sql_statements)
# 执行SQL语句创建表
await GenTableCRUD(auth=auth).create_table_by_sql(sql_statements)
await GenTableCRUD(auth=auth).create_table_by_sql(sql)
gen_table_list = await cls.get_gen_db_table_list_by_name_service(auth, table_names)
import_result = await cls.import_gen_table_service(auth, gen_table_list)
return import_result
@@ -261,7 +259,8 @@ class GenTableService:
async def get_gen_table_all_service(cls, auth: AuthSchema) -> List[GenTableOutSchema]:
"""获取所有业务表信息"""
gen_table_all = await GenTableCRUD(auth=auth).get_gen_table_all()
result = [GenTableOutSchema(**gen_table) for gen_table in CamelCaseUtil.transform_result(gen_table_all)]
gen_table_all_dict = [GenTableOutSchema.model_validate(gen_table).model_dump() for gen_table in gen_table_all]
result = [GenTableOutSchema(**gen_table) for gen_table in gen_table_all_dict]
return result
@classmethod
@@ -273,8 +272,8 @@ class GenTableService:
:param table_id: 业务表id
:return: 预览数据列表
"""
gen_table = GenTableOutSchema(
**CamelCaseUtil.transform_result(await GenTableCRUD(auth).get_gen_table_by_id(table_id))
gen_table = GenTableOutSchema.model_validate(
await GenTableCRUD(auth).get_gen_table_by_id(table_id)
)
await cls.set_sub_table(auth, gen_table)
await cls.set_pk_column(gen_table)
@@ -335,7 +334,7 @@ class GenTableService:
async def sync_db_service(cls, auth: AuthSchema, table_name: str) -> None:
"""同步数据库"""
gen_table = await GenTableCRUD(auth).get_gen_table_by_name(table_name)
table = GenTableSchema(**CamelCaseUtil.transform_result(gen_table))
table = GenTableSchema.model_validate(gen_table)
# 处理table.columns为None的情况
table_columns = table.columns or []
table_column_map = {column.column_name: column for column in table_columns}
@@ -388,7 +387,8 @@ class GenTableService:
gen_table_dao = GenTableCRUD(auth=auth)
sub_table = await gen_table_dao.get_gen_table_by_name(gen_table.sub_table_name)
if sub_table:
gen_table.sub_table = GenTableOutSchema(**CamelCaseUtil.transform_result(sub_table))
gen_table.sub_table = GenTableOutSchema.model_validate(sub_table)
@classmethod
async def set_pk_column(cls, gen_table: GenTableOutSchema) -> None:
@@ -471,11 +471,11 @@ class GenTableService:
raise CustomException(msg=f"业务表 {table_name} 不存在")
# 确保CamelCaseUtil.transform_result返回的是字典
transformed_result = CamelCaseUtil.transform_result(gen_table)
transformed_result = gen_table
if transformed_result is None:
raise CustomException(msg=f"业务表 {table_name} 数据转换失败")
gen_table_schema = GenTableOutSchema(**transformed_result)
gen_table_schema = GenTableOutSchema.model_validate(transformed_result)
await cls.set_sub_table(auth, gen_table_schema)
await cls.set_pk_column(gen_table_schema)
context = Jinja2TemplateUtil.prepare_context(gen_table_schema)
@@ -518,6 +518,6 @@ class GenTableColumnService:
"""获取业务表字段列表信息"""
gen_table_column_list_result = await GenTableColumnCRUD(auth).list_gen_table_column_crud({"table_id": table_id})
return [
GenTableColumnOutSchema(**gen_table_column)
for gen_table_column in CamelCaseUtil.transform_result(gen_table_column_list_result)
GenTableColumnOutSchema.model_validate(gen_table_column)
for gen_table_column in gen_table_column_list_result
]