Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ backend/.DS_Store
backend/venv
backend/logs
backend/*.db
backend/site
backend/env/*

frontend/__pycache__
frontend/.vscode
Expand All @@ -21,6 +21,8 @@ frontend/node_modules
frontend/dist
frontend/dist
frontend/.husky
frontend/.env.development
frontend/.env.production

devops/nginx/fastapp/dist
devops/nginx/fastdocs/dist
Expand Down
99 changes: 50 additions & 49 deletions backend/app/api/v1/module_generator/gencode/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,17 @@ async def get_gen_table_list(self, search: Optional[GenTableQueryParam] = None)
: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
Expand Down Expand Up @@ -141,7 +138,8 @@ async def delete_gen_table(self, ids: List[int]) -> None:
删除
"""
await self.db.execute(
delete(GenTableModel).where(GenTableModel.id.in_(ids))
delete(GenTableModel)
.where(GenTableModel.id.in_(ids))
)
await self.db.flush()

Expand Down Expand Up @@ -189,7 +187,7 @@ async def get_db_table_list(self, search: Optional[GenTableQueryParam] = None) -
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作为表名和注释
Expand All @@ -204,7 +202,7 @@ async def get_db_table_list(self, search: Optional[GenTableQueryParam] = None) -

# 动态条件构造
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)")
Expand All @@ -213,8 +211,8 @@ async def get_db_table_list(self, search: Optional[GenTableQueryParam] = None) -
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)")
Expand All @@ -223,7 +221,7 @@ async def get_db_table_list(self, search: Optional[GenTableQueryParam] = None) -
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()
Expand Down Expand Up @@ -284,7 +282,7 @@ async def get_db_table_list_by_names(self, table_names: List[str]) -> list[GenDB
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作为表名和注释
Expand All @@ -297,19 +295,19 @@ async def get_db_table_list_by_names(self, table_names: List[str]) -> list[GenDB
)
)

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}')")
)
gen_db_table_list = (await self.db.execute(query_sql)).fetchall()
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))
Expand All @@ -330,25 +328,25 @@ async def get_db_table_list_by_names(self, table_names: List[str]) -> list[GenDB
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]):
Expand All @@ -358,10 +356,18 @@ def __init__(self, auth: AuthSchema) -> None:
"""初始化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]:
"""
根据业务表名称获取业务表字段列表信息
Expand Down Expand Up @@ -421,28 +427,23 @@ async def get_gen_db_table_columns_by_name(self, table_name: str | None) -> List
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

Expand Down
4 changes: 2 additions & 2 deletions backend/app/api/v1/module_generator/gencode/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ def __init__(
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:
Expand Down
11 changes: 5 additions & 6 deletions backend/app/api/v1/module_generator/gencode/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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是)')
Expand Down
Loading