mirror of
https://github.com/fastapi-practices/fastapi_best_architecture.git
synced 2026-03-13 09:31:31 +08:00
Update code generator table columns (#590)
* Update code generator table columns * Update func doc
This commit is contained in:
@@ -30,7 +30,7 @@ class CRUDGenBusiness(CRUDPlus[GenBusiness]):
|
||||
:param name: 表名
|
||||
:return:
|
||||
"""
|
||||
return await self.select_model_by_column(db, table_name_en=name)
|
||||
return await self.select_model_by_column(db, table_name=name)
|
||||
|
||||
async def get_all(self, db: AsyncSession) -> Sequence[GenBusiness]:
|
||||
"""
|
||||
|
||||
@@ -20,13 +20,13 @@ class GenBusiness(Base):
|
||||
|
||||
id: Mapped[id_key] = mapped_column(init=False)
|
||||
app_name: Mapped[str] = mapped_column(String(50), comment='应用名称(英文)')
|
||||
table_name_en: Mapped[str] = mapped_column(String(255), unique=True, comment='表名称(英文)')
|
||||
table_name_zh: Mapped[str] = mapped_column(String(255), comment='表名称(中文)')
|
||||
table_simple_name_zh: Mapped[str] = mapped_column(String(255), comment='表名称(中文简称)')
|
||||
table_name: Mapped[str] = mapped_column(String(255), unique=True, comment='表名称(英文)')
|
||||
doc_comment: Mapped[str] = mapped_column(String(255), comment='文档注释(用于函数/参数文档)')
|
||||
table_comment: Mapped[str | None] = mapped_column(String(255), default=None, comment='表描述')
|
||||
# relate_model_fk: Mapped[int | None] = mapped_column(default=None, comment='关联表外键')
|
||||
schema_name: Mapped[str | None] = mapped_column(String(255), default=None, comment='Schema 名称 (默认为英文表名称)')
|
||||
filename: Mapped[str | None] = mapped_column(String(20), default=None, comment='基础文件名(默认为英文表名称)')
|
||||
class_name: Mapped[str | None] = mapped_column(String(50), default=None, comment='基础类名(默认为英文表名称)')
|
||||
schema_name: Mapped[str | None] = mapped_column(String(50), default=None, comment='Schema 名称 (默认为英文表名称)')
|
||||
filename: Mapped[str | None] = mapped_column(String(50), default=None, comment='基础文件名(默认为英文表名称)')
|
||||
default_datetime_column: Mapped[bool] = mapped_column(default=True, comment='是否存在默认时间列')
|
||||
api_version: Mapped[str] = mapped_column(String(20), default='v1', comment='代码生成 api 版本,默认为 v1')
|
||||
gen_path: Mapped[str | None] = mapped_column(String(255), default=None, comment='代码生成路径(默认为 app 根路径)')
|
||||
|
||||
@@ -11,10 +11,10 @@ class GenBusinessSchemaBase(SchemaBase):
|
||||
"""代码生成业务基础模型"""
|
||||
|
||||
app_name: str = Field(description='应用名称(英文)')
|
||||
table_name_en: str = Field(description='表名称(英文)')
|
||||
table_name_zh: str = Field(description='表名称(中文)')
|
||||
table_simple_name_zh: str = Field(description='表名称(中文简称)')
|
||||
table_name: str = Field(description='表名称(英文)')
|
||||
doc_comment: str = Field(description='文档注释(用于函数/参数文档)')
|
||||
table_comment: str | None = Field(None, description='表描述')
|
||||
class_name: str | None = Field(None, description='基础类名 (默认为英文表名称)')
|
||||
schema_name: str | None = Field(None, description='Schema 名称 (默认为英文表名称)')
|
||||
filename: str | None = Field(None, description='基础文件名(默认为英文表名称)')
|
||||
default_datetime_column: bool = Field(True, description='是否存在默认时间列')
|
||||
|
||||
@@ -41,7 +41,7 @@ class GenBusinessService:
|
||||
:return:
|
||||
"""
|
||||
async with async_db_session.begin() as db:
|
||||
business = await gen_business_dao.get_by_name(db, obj.table_name_en)
|
||||
business = await gen_business_dao.get_by_name(db, obj.table_name)
|
||||
if business:
|
||||
raise errors.ForbiddenError(msg='代码生成业务已存在')
|
||||
await gen_business_dao.create(db, obj)
|
||||
|
||||
@@ -61,10 +61,10 @@ class GenService:
|
||||
new_business = GenBusiness(
|
||||
**CreateGenBusinessParam(
|
||||
app_name=obj.app,
|
||||
table_name_en=table_name,
|
||||
table_name_zh=table_info[1] or ' '.join(table_name.split('_')),
|
||||
table_simple_name_zh=table_info[1] or table_name.split('_')[-1],
|
||||
table_name=table_name,
|
||||
doc_comment=table_info[1] or table_name.split('_')[-1],
|
||||
table_comment=table_info[1],
|
||||
class_name=table_name,
|
||||
schema_name=table_name,
|
||||
filename=table_name,
|
||||
).model_dump()
|
||||
@@ -194,8 +194,8 @@ class GenService:
|
||||
if code_folder.name == 'model':
|
||||
async with aiofiles.open(init_filepath, 'a', encoding='utf-8') as f:
|
||||
await f.write(
|
||||
f'from backend.app.{business.app_name}.model.{business.table_name_en} '
|
||||
f'import {to_pascal(business.table_name_en)}\n',
|
||||
f'from backend.app.{business.app_name}.model.{business.table_name} '
|
||||
f'import {to_pascal(business.table_name)}\n',
|
||||
)
|
||||
|
||||
# 写入代码文件
|
||||
@@ -229,8 +229,8 @@ class GenService:
|
||||
zf.writestr(
|
||||
init_filepath,
|
||||
f'{gen_template.init_content}'
|
||||
f'from backend.app.{business.app_name}.model.{business.table_name_en} '
|
||||
f'import {to_pascal(business.table_name_en)}\n',
|
||||
f'from backend.app.{business.app_name}.model.{business.table_name} '
|
||||
f'import {to_pascal(business.table_name)}\n',
|
||||
)
|
||||
|
||||
# api __init__.py
|
||||
|
||||
@@ -4,8 +4,8 @@ from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, Path, Query
|
||||
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name_en }} import Create{{ schema_name }}Param, Get{{ schema_name }}Detail, Update{{ schema_name }}Param
|
||||
from backend.app.{{ app_name }}.service.{{ table_name_en }}_service import {{ table_name_en }}_service
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name }} import Create{{ schema_name }}Param, Get{{ schema_name }}Detail, Update{{ schema_name }}Param
|
||||
from backend.app.{{ app_name }}.service.{{ table_name }}_service import {{ table_name }}_service
|
||||
from backend.common.pagination import DependsPagination, PageData, paging_data
|
||||
from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base
|
||||
from backend.common.security.jwt import DependsJwtAuth
|
||||
@@ -16,49 +16,49 @@ from backend.database.db import CurrentSession
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get('/{pk}', summary='获取{{ table_simple_name_zh }}详情', dependencies=[DependsJwtAuth])
|
||||
async def get_{{ table_name_en }}(pk: Annotated[int, Path(description='{{ table_simple_name_zh }} ID')]) -> ResponseSchemaModel[Get{{ schema_name }}Detail]:
|
||||
{{ table_name_en }} = await {{ table_name_en }}_service.get(pk=pk)
|
||||
return response_base.success(data={{ table_name_en }})
|
||||
@router.get('/{pk}', summary='获取{{ doc_comment }}详情', dependencies=[DependsJwtAuth])
|
||||
async def get_{{ table_name }}(pk: Annotated[int, Path(description='{{ doc_comment }} ID')]) -> ResponseSchemaModel[Get{{ schema_name }}Detail]:
|
||||
{{ table_name }} = await {{ table_name }}_service.get(pk=pk)
|
||||
return response_base.success(data={{ table_name }})
|
||||
|
||||
|
||||
@router.get(
|
||||
'',
|
||||
summary='分页获取所有{{ table_simple_name_zh }}',
|
||||
summary='分页获取所有{{ doc_comment }}',
|
||||
dependencies=[
|
||||
DependsJwtAuth,
|
||||
DependsPagination,
|
||||
],
|
||||
)
|
||||
async def get_pagination_{{ table_name_en }}s(db: CurrentSession) -> ResponseSchemaModel[PageData[Get{{ schema_name }}Detail]]:
|
||||
{{ table_name_en }}_select = await {{ table_name_en }}_service.get_select()
|
||||
page_data = await paging_data(db, {{ table_name_en }}_select)
|
||||
async def get_pagination_{{ table_name }}s(db: CurrentSession) -> ResponseSchemaModel[PageData[Get{{ schema_name }}Detail]]:
|
||||
{{ table_name }}_select = await {{ table_name }}_service.get_select()
|
||||
page_data = await paging_data(db, {{ table_name }}_select)
|
||||
return response_base.success(data=page_data)
|
||||
|
||||
|
||||
@router.post(
|
||||
'',
|
||||
summary='创建{{ table_simple_name_zh }}',
|
||||
summary='创建{{ doc_comment }}',
|
||||
dependencies=[
|
||||
Depends(RequestPermission('{{ permission }}:add')),
|
||||
DependsRBAC,
|
||||
],
|
||||
)
|
||||
async def create_{{ table_name_en }}(obj: Create{{ schema_name }}Param) -> ResponseModel:
|
||||
await {{ table_name_en }}_service.create(obj=obj)
|
||||
async def create_{{ table_name }}(obj: Create{{ schema_name }}Param) -> ResponseModel:
|
||||
await {{ table_name }}_service.create(obj=obj)
|
||||
return response_base.success()
|
||||
|
||||
|
||||
@router.put(
|
||||
'/{pk}',
|
||||
summary='更新{{ table_simple_name_zh }}',
|
||||
summary='更新{{ doc_comment }}',
|
||||
dependencies=[
|
||||
Depends(RequestPermission('{{ permission }}:edit')),
|
||||
DependsRBAC,
|
||||
],
|
||||
)
|
||||
async def update_{{ table_name_en }}(pk: Annotated[int, Path(description='{{ table_simple_name_zh }} ID')], obj: Update{{ schema_name }}Param) -> ResponseModel:
|
||||
count = await {{ table_name_en }}_service.update(pk=pk, obj=obj)
|
||||
async def update_{{ table_name }}(pk: Annotated[int, Path(description='{{ doc_comment }} ID')], obj: Update{{ schema_name }}Param) -> ResponseModel:
|
||||
count = await {{ table_name }}_service.update(pk=pk, obj=obj)
|
||||
if count > 0:
|
||||
return response_base.success()
|
||||
return response_base.fail()
|
||||
@@ -66,14 +66,14 @@ async def update_{{ table_name_en }}(pk: Annotated[int, Path(description='{{ tab
|
||||
|
||||
@router.delete(
|
||||
'',
|
||||
summary='批量删除{{ table_simple_name_zh }}',
|
||||
summary='批量删除{{ doc_comment }}',
|
||||
dependencies=[
|
||||
Depends(RequestPermission('{{ permission }}:del')),
|
||||
DependsRBAC,
|
||||
],
|
||||
)
|
||||
async def delete_{{ table_name_en }}(pk: Annotated[list[int], Query(description='{{ table_simple_name_zh }} ID 列表')]) -> ResponseModel:
|
||||
count = await {{ table_name_en }}_service.delete(pk=pk)
|
||||
async def delete_{{ table_name }}(pk: Annotated[list[int], Query(description='{{ doc_comment }} ID 列表')]) -> ResponseModel:
|
||||
count = await {{ table_name }}_service.delete(pk=pk)
|
||||
if count > 0:
|
||||
return response_base.success()
|
||||
return response_base.fail()
|
||||
|
||||
@@ -6,28 +6,28 @@ from sqlalchemy import Select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy_crud_plus import CRUDPlus
|
||||
|
||||
from backend.app.{{ app_name }}.model import {{ table_name_class }}
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name_en }} import Create{{ schema_name }}Param, Update{{ schema_name }}Param
|
||||
from backend.app.{{ app_name }}.model import {{ class_name }}
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name }} import Create{{ schema_name }}Param, Update{{ schema_name }}Param
|
||||
|
||||
|
||||
class CRUD{{ table_name_class }}(CRUDPlus[{{ schema_name }}]):
|
||||
async def get(self, db: AsyncSession, pk: int) -> {{ table_name_class }} | None:
|
||||
class CRUD{{ class_name }}(CRUDPlus[{{ schema_name }}]):
|
||||
async def get(self, db: AsyncSession, pk: int) -> {{ class_name }} | None:
|
||||
"""
|
||||
获取{{ table_name_zh }}
|
||||
获取{{ doc_comment }}
|
||||
|
||||
:param db: 数据库会话
|
||||
:param pk: {{ table_simple_name_zh }} ID
|
||||
:param pk: {{ doc_comment }} ID
|
||||
:return:
|
||||
"""
|
||||
return await self.select_model(db, pk)
|
||||
|
||||
async def get_list(self) -> Select:
|
||||
"""获取{{ table_name_zh }}列表"""
|
||||
"""获取{{ doc_comment }}列表"""
|
||||
return await self.select_order('created_time', 'desc')
|
||||
|
||||
async def get_all(self, db: AsyncSession) -> Sequence[{{ table_name_class }}]:
|
||||
async def get_all(self, db: AsyncSession) -> Sequence[{{ class_name }}]:
|
||||
"""
|
||||
获取所有{{ table_name_zh }}
|
||||
获取所有{{ doc_comment }}
|
||||
|
||||
:param db: 数据库会话
|
||||
:return:
|
||||
@@ -36,34 +36,34 @@ class CRUD{{ table_name_class }}(CRUDPlus[{{ schema_name }}]):
|
||||
|
||||
async def create(self, db: AsyncSession, obj: Create{{ schema_name }}Param) -> None:
|
||||
"""
|
||||
创建{{ table_name_zh }}
|
||||
创建{{ doc_comment }}
|
||||
|
||||
:param db: 数据库会话
|
||||
:param obj: 创建{{ table_simple_name_zh }} 参数
|
||||
:param obj: 创建{{ doc_comment }}参数
|
||||
:return:
|
||||
"""
|
||||
await self.create_model(db, obj)
|
||||
|
||||
async def update(self, db: AsyncSession, pk: int, obj: Update{{ schema_name }}Param) -> int:
|
||||
"""
|
||||
更新{{ table_name_zh }}
|
||||
更新{{ doc_comment }}
|
||||
|
||||
:param db: 数据库会话
|
||||
:param pk: {{ table_simple_name_zh }} ID
|
||||
:param obj: 更新 {{ table_simple_name_zh }} 参数
|
||||
:param pk: {{ doc_comment }} ID
|
||||
:param obj: 更新 {{ doc_comment }}参数
|
||||
:return:
|
||||
"""
|
||||
return await self.update_model(db, pk, obj)
|
||||
|
||||
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
|
||||
"""
|
||||
删除{{ table_name_zh }}
|
||||
删除{{ doc_comment }}
|
||||
|
||||
:param db: 数据库会话
|
||||
:param pk: {{ table_simple_name_zh }} ID
|
||||
:param pk: {{ doc_comment }} ID
|
||||
:return:
|
||||
"""
|
||||
return await self.delete_model_by_column(db, allow_multiple=True, id__in=pk)
|
||||
|
||||
|
||||
{{ table_name_en }}_dao: CRUD{{ table_name_class }} = CRUD{{ table_name_class }}({{ table_name_class }})
|
||||
{{ instance_name }}_dao: CRUD{{ class_name }} = CRUD{{ class_name }}({{ class_name }})
|
||||
|
||||
@@ -15,10 +15,10 @@ from sqlalchemy.orm import Mapped, mapped_column
|
||||
from backend.common.model import {% if default_datetime_column %}Base{% else %}MappedBase{% endif %}, id_key
|
||||
|
||||
|
||||
class {{ table_name_class }}({% if default_datetime_column %}Base{% else %}MappedBase{% endif %}):
|
||||
"""{{ table_name_zh }}"""
|
||||
class {{ class_name }}({% if default_datetime_column %}Base{% else %}MappedBase{% endif %}):
|
||||
"""{{ table_comment }}"""
|
||||
|
||||
__tablename__ = '{{ table_name_en }}'
|
||||
__tablename__ = '{{ table_name }}'
|
||||
|
||||
id: Mapped[id_key] = mapped_column(init=False)
|
||||
{% for model in models %}
|
||||
|
||||
@@ -8,7 +8,7 @@ from backend.common.schema import SchemaBase
|
||||
|
||||
|
||||
class {{ schema_name }}SchemaBase(SchemaBase):
|
||||
"""{{ table_simple_name_zh }}基础模型"""
|
||||
"""{{ doc_comment }}基础模型"""
|
||||
{% for model in models %}
|
||||
{{ model.name }}: {% if model.nullable %}{{ model.pd_type }} | None = Field(None, description='{{ model.comment }}'){% else %}{{ model.pd_type }} = Field(description='{{ model.comment }}'){% endif %}
|
||||
|
||||
@@ -16,15 +16,15 @@ class {{ schema_name }}SchemaBase(SchemaBase):
|
||||
|
||||
|
||||
class Create{{ schema_name }}Param({{ schema_name }}SchemaBase):
|
||||
"""创建{{ table_simple_name_zh }}参数"""
|
||||
"""创建{{ doc_comment }}参数"""
|
||||
|
||||
|
||||
class Update{{ schema_name }}Param({{ schema_name }}SchemaBase):
|
||||
"""更新{{ table_simple_name_zh }}参数"""
|
||||
"""更新{{ doc_comment }}参数"""
|
||||
|
||||
|
||||
class Get{{ schema_name }}Detail({{ schema_name }}SchemaBase):
|
||||
"""{{ table_simple_name_zh }}详情"""
|
||||
"""{{ doc_comment }}详情"""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
@@ -4,75 +4,75 @@ from typing import Sequence
|
||||
|
||||
from sqlalchemy import Select
|
||||
|
||||
from backend.app.{{ app_name }}.crud.crud_{{ table_name_en }} import {{ table_name_en }}_dao
|
||||
from backend.app.{{ app_name }}.model import {{ table_name_class }}
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name_en }} import Create{{ schema_name }}Param, Update{{ schema_name }}Param
|
||||
from backend.app.{{ app_name }}.crud.crud_{{ table_name }} import {{ table_name }}_dao
|
||||
from backend.app.{{ app_name }}.model import {{ class_name }}
|
||||
from backend.app.{{ app_name }}.schema.{{ table_name }} import Create{{ schema_name }}Param, Update{{ schema_name }}Param
|
||||
from backend.common.exception import errors
|
||||
from backend.database.db import async_db_session
|
||||
|
||||
|
||||
class {{ table_name_class }}Service:
|
||||
class {{ class_name }}Service:
|
||||
@staticmethod
|
||||
async def get(*, pk: int) -> {{ table_name_class }}:
|
||||
async def get(*, pk: int) -> {{ class_name }}:
|
||||
"""
|
||||
获取{{ table_simple_name_zh }}
|
||||
获取{{ doc_comment }}
|
||||
|
||||
:param pk: {{ table_simple_name_zh }} ID
|
||||
:param pk: {{ doc_comment }} ID
|
||||
:return:
|
||||
"""
|
||||
async with async_db_session() as db:
|
||||
{{ table_name_en }} = await {{ table_name_en }}_dao.get(db, pk)
|
||||
if not {{ table_name_en }}:
|
||||
raise errors.NotFoundError(msg='{{ table_simple_name_zh }}不存在')
|
||||
return {{ table_name_en }}
|
||||
{{ table_name }} = await {{ table_name }}_dao.get(db, pk)
|
||||
if not {{ table_name }}:
|
||||
raise errors.NotFoundError(msg='{{ doc_comment }}不存在')
|
||||
return {{ table_name }}
|
||||
|
||||
@staticmethod
|
||||
async def get_select() -> Select:
|
||||
"""获取{{ table_simple_name_zh }}查询对象"""
|
||||
return await {{ table_name_en }}_dao.get_list()
|
||||
"""获取{{ doc_comment }}查询对象"""
|
||||
return await {{ table_name }}_dao.get_list()
|
||||
|
||||
@staticmethod
|
||||
async def get_all() -> Sequence[{{ table_name_class }}]:
|
||||
"""获取所有{{ table_simple_name_zh }}"""
|
||||
async def get_all() -> Sequence[{{ class_name }}]:
|
||||
"""获取所有{{ doc_comment }}"""
|
||||
async with async_db_session() as db:
|
||||
{{ table_name_en }}s = await {{ table_name_en }}_dao.get_all(db)
|
||||
return {{ table_name_en }}s
|
||||
{{ table_name }}s = await {{ table_name }}_dao.get_all(db)
|
||||
return {{ table_name }}s
|
||||
|
||||
@staticmethod
|
||||
async def create(*, obj: Create{{ schema_name }}Param) -> None:
|
||||
"""
|
||||
创建{{ table_simple_name_zh }}
|
||||
创建{{ doc_comment }}
|
||||
|
||||
:param obj: 创建{{ table_simple_name_zh }}参数
|
||||
:param obj: 创建{{ doc_comment }}参数
|
||||
:return:
|
||||
"""
|
||||
async with async_db_session.begin() as db:
|
||||
await {{ table_name_en }}_dao.create(db, obj)
|
||||
await {{ table_name }}_dao.create(db, obj)
|
||||
|
||||
@staticmethod
|
||||
async def update(*, pk: int, obj: Update{{ schema_name }}Param) -> int:
|
||||
"""
|
||||
更新{{ table_simple_name_zh }}
|
||||
更新{{ doc_comment }}
|
||||
|
||||
:param pk: {{ table_simple_name_zh }} ID
|
||||
:param obj: 更新{{ table_simple_name_zh }}参数
|
||||
:param pk: {{ doc_comment }} ID
|
||||
:param obj: 更新{{ doc_comment }}参数
|
||||
:return:
|
||||
"""
|
||||
async with async_db_session.begin() as db:
|
||||
count = await {{ table_name_en }}_dao.update(db, pk, obj)
|
||||
count = await {{ table_name }}_dao.update(db, pk, obj)
|
||||
return count
|
||||
|
||||
@staticmethod
|
||||
async def delete(*, pk: list[int]) -> int:
|
||||
"""
|
||||
删除{{ table_simple_name_zh }}
|
||||
删除{{ doc_comment }}
|
||||
|
||||
:param pk: {{ table_simple_name_zh }} ID 列表
|
||||
:param pk: {{ doc_comment }} ID 列表
|
||||
:return:
|
||||
"""
|
||||
async with async_db_session.begin() as db:
|
||||
count = await {{ table_name_en }}_dao.delete(db, pk)
|
||||
count = await {{ table_name }}_dao.delete(db, pk)
|
||||
return count
|
||||
|
||||
|
||||
{{ table_name_en }}_service: {{ table_name_class }}Service = {{ table_name_class }}Service()
|
||||
{{ instance_name }}_service: {{ class_name }}Service = {{ class_name }}Service()
|
||||
|
||||
@@ -88,14 +88,14 @@ class GenTemplate:
|
||||
"""
|
||||
return {
|
||||
'app_name': business.app_name,
|
||||
'table_name_en': to_snake(business.table_name_en),
|
||||
'table_name_class': to_pascal(business.table_name_en),
|
||||
'table_name_zh': business.table_name_zh,
|
||||
'table_simple_name_zh': business.table_simple_name_zh,
|
||||
'table_name': to_snake(business.table_name),
|
||||
'doc_comment': business.doc_comment,
|
||||
'table_comment': business.table_comment,
|
||||
'class_name': to_pascal(business.class_name),
|
||||
'instance_name': to_snake(business.class_name),
|
||||
'schema_name': to_pascal(business.schema_name),
|
||||
'default_datetime_column': business.default_datetime_column,
|
||||
'permission': str(business.table_name_en.replace('_', ':')),
|
||||
'permission': str(business.table_name.replace('_', ':')),
|
||||
'database_type': settings.DATABASE_TYPE,
|
||||
'models': models,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user