mirror of
https://github.com/fastapi-practices/fastapi_best_architecture.git
synced 2025-08-26 13:26:04 +08:00
Optimize and normalize the code generator (#430)
This commit is contained in:
@ -33,7 +33,7 @@ async def get_all_businesses() -> ResponseModel:
|
||||
|
||||
@router.get('/businesses/{pk}', summary='获取代码生成业务详情', dependencies=[DependsJwtAuth])
|
||||
async def get_business(pk: Annotated[int, Path(...)]) -> ResponseModel:
|
||||
business = await gen_service.get_business_with_model(pk=pk)
|
||||
business = await gen_business_service.get(pk=pk)
|
||||
data = GetGenBusinessListDetails(**select_as_dict(business))
|
||||
return response_base.success(data=data)
|
||||
|
||||
@ -89,6 +89,12 @@ async def delete_business(pk: Annotated[int, Path(...)]) -> ResponseModel:
|
||||
return response_base.fail()
|
||||
|
||||
|
||||
@router.get('/models/types', summary='获取代码生成模型列类型', dependencies=[DependsJwtAuth])
|
||||
async def get_model_types() -> ResponseModel:
|
||||
model_types = await gen_model_service.get_types()
|
||||
return response_base.success(data=model_types)
|
||||
|
||||
|
||||
@router.get('/models/{pk}', summary='获取代码生成模型详情', dependencies=[DependsJwtAuth])
|
||||
async def get_model(pk: Annotated[int, Path(...)]) -> ResponseModel:
|
||||
model = await gen_model_service.get(pk=pk)
|
||||
|
@ -2,21 +2,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Sequence
|
||||
|
||||
from sqlalchemy import Row, select, text
|
||||
from sqlalchemy import Row, text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from backend.app.generator.model import GenBusiness
|
||||
|
||||
|
||||
class CRUDGen:
|
||||
@staticmethod
|
||||
async def get_business_with_model(db: AsyncSession, business_id: int) -> GenBusiness:
|
||||
stmt = select(GenBusiness).options(selectinload(GenBusiness.gen_model)).where(GenBusiness.id == business_id)
|
||||
result = await db.execute(stmt)
|
||||
data = result.scalars().first()
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
async def get_all_tables(db: AsyncSession, table_schema: str) -> Sequence[str]:
|
||||
stmt = text(
|
||||
|
@ -2,6 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Sequence
|
||||
|
||||
from sqlalchemy import update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy_crud_plus import CRUDPlus
|
||||
|
||||
@ -34,6 +35,7 @@ class CRUDGenModel(CRUDPlus[GenModel]):
|
||||
|
||||
:param db:
|
||||
:param obj_in:
|
||||
:param pd_type:
|
||||
:return:
|
||||
"""
|
||||
await self.create_model(db, obj_in, pd_type=pd_type)
|
||||
@ -45,9 +47,12 @@ class CRUDGenModel(CRUDPlus[GenModel]):
|
||||
:param db:
|
||||
:param pk:
|
||||
:param obj_in:
|
||||
:param pd_type:
|
||||
:return:
|
||||
"""
|
||||
return await self.update_model_by_column(db, obj_in, id=pk, pd_type=pd_type)
|
||||
stmt = update(self.model).where(self.model.id == pk).values(**obj_in.model_dump(), pd_type=pd_type)
|
||||
result = await db.execute(stmt)
|
||||
return result.rowcount
|
||||
|
||||
async def delete(self, db: AsyncSession, pk: int) -> int:
|
||||
"""
|
||||
|
@ -2,7 +2,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from pydantic import ConfigDict, Field, field_validator
|
||||
|
||||
from backend.common.enums import GenModelColumnType
|
||||
from backend.common.schema import SchemaBase
|
||||
from backend.utils.type_conversion import sql_type_to_sqlalchemy
|
||||
|
||||
@ -10,7 +9,7 @@ from backend.utils.type_conversion import sql_type_to_sqlalchemy
|
||||
class GenModelSchemaBase(SchemaBase):
|
||||
name: str
|
||||
comment: str | None = None
|
||||
type: GenModelColumnType = Field(GenModelColumnType.VARCHAR)
|
||||
type: str
|
||||
default: str | None = None
|
||||
sort: int
|
||||
length: int
|
||||
|
@ -5,6 +5,7 @@ from typing import Sequence
|
||||
from backend.app.generator.crud.crud_gen_model import gen_model_dao
|
||||
from backend.app.generator.model import GenModel
|
||||
from backend.app.generator.schema.gen_model import CreateGenModelParam, UpdateGenModelParam
|
||||
from backend.common.enums import GenModelMySQLColumnType
|
||||
from backend.common.exception import errors
|
||||
from backend.database.db_mysql import async_db_session
|
||||
from backend.utils.type_conversion import sql_type_to_pydantic
|
||||
@ -17,6 +18,12 @@ class GenModelService:
|
||||
gen_model = await gen_model_dao.get(db, pk)
|
||||
return gen_model
|
||||
|
||||
@staticmethod
|
||||
async def get_types() -> list[str]:
|
||||
types = GenModelMySQLColumnType.get_member_keys()
|
||||
types.sort()
|
||||
return types
|
||||
|
||||
@staticmethod
|
||||
async def get_by_business(*, business_id: int) -> Sequence[GenModel]:
|
||||
async with async_db_session() as db:
|
||||
|
@ -18,20 +18,14 @@ from backend.app.generator.model import GenBusiness
|
||||
from backend.app.generator.schema.gen_business import CreateGenBusinessParam
|
||||
from backend.app.generator.schema.gen_model import CreateGenModelParam
|
||||
from backend.app.generator.service.gen_model_service import gen_model_service
|
||||
from backend.common.enums import GenModelColumnType
|
||||
from backend.common.exception import errors
|
||||
from backend.core.path_conf import BasePath
|
||||
from backend.database.db_mysql import async_db_session
|
||||
from backend.utils.gen_template import gen_template
|
||||
from backend.utils.type_conversion import sql_type_to_pydantic
|
||||
|
||||
|
||||
class GenService:
|
||||
@staticmethod
|
||||
async def get_business_with_model(*, pk: int) -> GenBusiness:
|
||||
async with async_db_session() as db:
|
||||
business = await gen_dao.get_business_with_model(db, pk)
|
||||
return business
|
||||
|
||||
@staticmethod
|
||||
async def get_tables(*, table_schema: str) -> Sequence[str]:
|
||||
async with async_db_session() as db:
|
||||
@ -60,19 +54,18 @@ class GenService:
|
||||
column_info = await gen_dao.get_all_columns(db, table_schema, table_name)
|
||||
for column in column_info:
|
||||
column_type = column[-1].split('(')[0].upper()
|
||||
pd_type = sql_type_to_pydantic(column_type)
|
||||
model_data = {
|
||||
'name': column[0],
|
||||
'comment': column[-2],
|
||||
'type': column_type,
|
||||
'sort': column[-3],
|
||||
'length': column[-1].split('(')[1][:-1]
|
||||
if column_type == GenModelColumnType.CHAR or column_type == GenModelColumnType.VARCHAR
|
||||
else 0,
|
||||
'length': column[-1].split('(')[1][:-1] if pd_type == 'str' and '(' in column[-1] else 0,
|
||||
'is_pk': column[1],
|
||||
'is_nullable': column[2],
|
||||
'gen_business_id': new_business.id,
|
||||
}
|
||||
await gen_model_dao.create(db, CreateGenModelParam(**model_data))
|
||||
await gen_model_dao.create(db, CreateGenModelParam(**model_data), pd_type=pd_type)
|
||||
|
||||
@staticmethod
|
||||
async def render_tpl_code(*, business: GenBusiness) -> dict:
|
||||
|
@ -90,50 +90,151 @@ class UserSocialType(StrEnum):
|
||||
linuxdo = 'LinuxDo'
|
||||
|
||||
|
||||
class GenModelColumnType(StrEnum):
|
||||
"""代码生成模型列类型"""
|
||||
class GenModelMySQLColumnType(StrEnum):
|
||||
"""代码生成模型列类型(MySQL)"""
|
||||
|
||||
BIGINT = 'BIGINT'
|
||||
BINARY = 'BINARY'
|
||||
BIT = 'BIT'
|
||||
BLOB = 'BLOB'
|
||||
BOOL = 'BOOL'
|
||||
BOOLEAN = 'BOOLEAN'
|
||||
CHAR = 'CHAR'
|
||||
DATE = 'DATE'
|
||||
DATETIME = 'DATETIME'
|
||||
DECIMAL = 'DECIMAL'
|
||||
DOUBLE = 'DOUBLE'
|
||||
DOUBLE_PRECISION = 'DOUBLE PRECISION'
|
||||
ENUM = 'ENUM'
|
||||
FLOAT = 'FLOAT'
|
||||
GEOMETRY = 'GEOMETRY'
|
||||
GEOMETRYCOLLECTION = 'GEOMETRYCOLLECTION'
|
||||
INT = 'INT'
|
||||
INTEGER = 'INTEGER'
|
||||
JSON = 'JSON'
|
||||
LINESTRING = 'LINESTRING'
|
||||
LONGBLOB = 'LONGBLOB'
|
||||
LONGTEXT = 'LONGTEXT'
|
||||
MEDIUMBLOB = 'MEDIUMBLOB'
|
||||
MEDIUMINT = 'MEDIUMINT'
|
||||
MEDIUMTEXT = 'MEDIUMTEXT'
|
||||
MULTILINESTRING = 'MULTILINESTRING'
|
||||
MULTIPOINT = 'MULTIPOINT'
|
||||
MULTIPOLYGON = 'MULTIPOLYGON'
|
||||
NUMERIC = 'NUMERIC'
|
||||
POINT = 'POINT'
|
||||
POLYGON = 'POLYGON'
|
||||
REAL = 'REAL'
|
||||
SERIAL = 'SERIAL'
|
||||
SET = 'SET'
|
||||
SMALLINT = 'SMALLINT'
|
||||
TEXT = 'TEXT'
|
||||
TIME = 'TIME'
|
||||
TIMESTAMP = 'TIMESTAMP'
|
||||
TINYBLOB = 'TINYBLOB'
|
||||
TINYINT = 'TINYINT'
|
||||
TINYTEXT = 'TINYTEXT'
|
||||
VARBINARY = 'VARBINARY'
|
||||
VARCHAR = 'VARCHAR'
|
||||
YEAR = 'YEAR'
|
||||
# Python 类型映射
|
||||
BIGINT = 'int'
|
||||
BigInteger = 'int' # BIGINT
|
||||
BINARY = 'bytes'
|
||||
BLOB = 'bytes'
|
||||
BOOLEAN = 'bool' # BOOL
|
||||
Boolean = 'bool' # BOOL
|
||||
CHAR = 'str'
|
||||
CLOB = 'str'
|
||||
DATE = 'date'
|
||||
Date = 'date' # DATE
|
||||
DATETIME = 'datetime'
|
||||
DateTime = 'datetime' # DATETIME
|
||||
DECIMAL = 'Decimal'
|
||||
DOUBLE = 'float'
|
||||
Double = 'float' # DOUBLE
|
||||
DOUBLE_PRECISION = 'float'
|
||||
Enum = 'Enum' # Enum()
|
||||
FLOAT = 'float'
|
||||
Float = 'float' # FLOAT
|
||||
INT = 'int' # INTEGER
|
||||
INTEGER = 'int'
|
||||
Integer = 'int' # INTEGER
|
||||
Interval = 'timedelta' # DATETIME
|
||||
JSON = 'dict'
|
||||
LargeBinary = 'bytes' # BLOB
|
||||
NCHAR = 'str'
|
||||
NUMERIC = 'Decimal'
|
||||
Numeric = 'Decimal' # NUMERIC
|
||||
NVARCHAR = 'str' # String
|
||||
PickleType = 'bytes' # BLOB
|
||||
REAL = 'float'
|
||||
SMALLINT = 'int'
|
||||
SmallInteger = 'int' # SMALLINT
|
||||
String = 'str' # String
|
||||
TEXT = 'str'
|
||||
Text = 'str' # TEXT
|
||||
TIME = 'time'
|
||||
Time = 'time' # TIME
|
||||
TIMESTAMP = 'datetime'
|
||||
Unicode = 'str' # String
|
||||
UnicodeText = 'str' # TEXT
|
||||
UUID = 'str | UUID'
|
||||
Uuid = 'str' # CHAR(32)
|
||||
VARBINARY = 'bytes'
|
||||
VARCHAR = 'str' # String
|
||||
|
||||
# sa.dialects.mysql 导入
|
||||
BIT = 'bool'
|
||||
ENUM = 'Enum'
|
||||
LONGBLOB = 'bytes'
|
||||
LONGTEXT = 'str'
|
||||
MEDIUMBLOB = 'bytes'
|
||||
MEDIUMINT = 'int'
|
||||
MEDIUMTEXT = 'str'
|
||||
SET = 'list[str]'
|
||||
TINYBLOB = 'bytes'
|
||||
TINYINT = 'int'
|
||||
TINYTEXT = 'str'
|
||||
YEAR = 'int'
|
||||
|
||||
|
||||
class GenModelPostgreSQLColumnType(StrEnum):
|
||||
"""代码生成模型列类型(PostgreSQL),仅作为数据保留,并未实施"""
|
||||
|
||||
# Python 类型映射
|
||||
BIGINT = 'int'
|
||||
BigInteger = 'int' # BIGINT
|
||||
BINARY = 'bytes'
|
||||
BLOB = 'bytes'
|
||||
BOOLEAN = 'bool'
|
||||
Boolean = 'bool' # BOOLEAN
|
||||
CHAR = 'str'
|
||||
CLOB = 'str'
|
||||
DATE = 'date'
|
||||
Date = 'date' # DATE
|
||||
DATETIME = 'datetime'
|
||||
DateTime = 'datetime' # TIMESTAMP WITHOUT TIME ZONE
|
||||
DECIMAL = 'Decimal'
|
||||
DOUBLE = 'float'
|
||||
Double = 'float' # DOUBLE PRECISION
|
||||
DOUBLE_PRECISION = 'float' # DOUBLE PRECISION
|
||||
Enum = 'Enum' # Enum(name='enum')
|
||||
FLOAT = 'float'
|
||||
Float = 'float' # FLOAT
|
||||
INT = 'int' # INTEGER
|
||||
INTEGER = 'int'
|
||||
Integer = 'int' # INTEGER
|
||||
Interval = 'timedelta' # INTERVAL
|
||||
JSON = 'dict'
|
||||
LargeBinary = 'bytes' # BYTEA
|
||||
NCHAR = 'str'
|
||||
NUMERIC = 'Decimal'
|
||||
Numeric = 'Decimal' # NUMERIC
|
||||
NVARCHAR = 'str' # String
|
||||
PickleType = 'bytes' # BYTEA
|
||||
REAL = 'float'
|
||||
SMALLINT = 'int'
|
||||
SmallInteger = 'int' # SMALLINT
|
||||
String = 'str' # String
|
||||
TEXT = 'str'
|
||||
Text = 'str' # TEXT
|
||||
TIME = 'time' # TIME WITHOUT TIME ZONE
|
||||
Time = 'time' # TIME WITHOUT TIME ZONE
|
||||
TIMESTAMP = 'datetime' # TIMESTAMP WITHOUT TIME ZONE
|
||||
Unicode = 'str' # String
|
||||
UnicodeText = 'str' # TEXT
|
||||
UUID = 'str | UUID'
|
||||
Uuid = 'str'
|
||||
VARBINARY = 'bytes'
|
||||
VARCHAR = 'str' # String
|
||||
|
||||
# sa.dialects.postgresql 导入
|
||||
ARRAY = 'list'
|
||||
BIT = 'bool'
|
||||
BYTEA = 'bytes'
|
||||
CIDR = 'str'
|
||||
CITEXT = 'str'
|
||||
DATEMULTIRANGE = 'list[date]'
|
||||
DATERANGE = 'tuple[date, date]'
|
||||
DOMAIN = 'str'
|
||||
ENUM = 'Enum'
|
||||
HSTORE = 'dict'
|
||||
INET = 'str'
|
||||
INT4MULTIRANGE = 'list[int]'
|
||||
INT4RANGE = 'tuple[int, int]'
|
||||
INT8MULTIRANGE = 'list[int]'
|
||||
INT8RANGE = 'tuple[int, int]'
|
||||
INTERVAL = 'timedelta'
|
||||
JSONB = 'dict'
|
||||
JSONPATH = 'str'
|
||||
MACADDR = 'str'
|
||||
MACADDR8 = 'str'
|
||||
MONEY = 'Decimal'
|
||||
NUMMULTIRANGE = 'list[Decimal]'
|
||||
NUMRANGE = 'tuple[Decimal, Decimal]'
|
||||
OID = 'int'
|
||||
REGCLASS = 'str'
|
||||
REGCONFIG = 'str'
|
||||
TSMULTIRANGE = 'list[datetime]'
|
||||
TSQUERY = 'str'
|
||||
TSRANGE = 'tuple[datetime, datetime]'
|
||||
TSTZMULTIRANGE = 'list[datetime]'
|
||||
TSTZRANGE = 'tuple[datetime, datetime]'
|
||||
TSVECTOR = 'str'
|
||||
|
@ -5,47 +5,45 @@ INSERT INTO fba.sys_menu (id, title, name, level, sort, icon, path, menu_type, c
|
||||
VALUES (1, '测试', 'test', 0, 0, '', null, 0, null, null, 0, 0, 1, null, null, '2023-07-27 19:14:10', null),
|
||||
(2, '仪表盘', 'dashboard', 0, 0, 'IconDashboard', 'dashboard', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:15:45', null),
|
||||
(3, '工作台', 'Workplace', 0, 0, null, 'workplace', 1, '/dashboard/workplace/index.vue', null, 1, 1, 1, null, 2, '2023-07-27 19:17:59', null),
|
||||
(4, 'arco官网', 'arcoWebsite', 0, 888, 'IconLink', 'https://arco.design', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:23', null),
|
||||
(5, '日志', 'log', 0, 66, 'IconBug', 'log', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:59', null),
|
||||
(6, '登录日志', 'Login', 0, 0, null, 'login', 1, '/log/login/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:20:56', null),
|
||||
(7, '操作日志', 'Opera', 0, 0, null, 'opera', 1, '/log/opera/index.vue', null, 1, 1, 1, null, 5, '2023-07-27 19:21:28', null),
|
||||
(8, '常见问题', 'faq', 0, 999, 'IconQuestion', 'https://arco.design/vue/docs/pro/faq', 1, null, null, 1, 1, 1, null, null, '2023-07-27 19:22:24', null),
|
||||
(9, '系统管理', 'admin', 0, 6, 'IconSettings', 'admin', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:23:00', null),
|
||||
(10, '部门管理', 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:23:42', null),
|
||||
(11, '新增', '', 0, 0, null, null, 2, null, 'sys:dept:add', 1, 1, 1, null, 10, '2024-01-07 11:37:00', null),
|
||||
(12, '编辑', '', 0, 0, null, null, 2, null, 'sys:dept:edit', 1, 1, 1, null, 10, '2024-01-07 11:37:29', null),
|
||||
(13, '删除', '', 0, 0, null, null, 2, null, 'sys:dept:del', 1, 1, 1, null, 10, '2024-01-07 11:37:44', null),
|
||||
(14, 'API管理', 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:24:12', null),
|
||||
(15, '新增', '', 0, 0, null, null, 2, null, 'sys:api:add', 1, 1, 1, null, 14, '2024-01-07 11:57:09', null),
|
||||
(16, '编辑', '', 0, 0, null, null, 2, null, 'sys:api:edit', 1, 1, 1, null, 14, '2024-01-07 11:57:44', null),
|
||||
(17, '删除', '', 0, 0, null, null, 2, null, 'sys:api:del', 1, 1, 1, null, 14, '2024-01-07 11:57:56', null),
|
||||
(18, '用户管理', 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:13', null),
|
||||
(19, '编辑用户角色', '', 0, 0, null, null, 2, null, 'sys:user:role:edit', 1, 1, 1, null, 18, '2024-01-07 12:04:20', null),
|
||||
(20, '注销', '', 0, 0, null, null, 2, null, 'sys:user:del', 1, 1, 1, '用户注销 != 用户登出,注销之后用户将从数据库删除', 18, '2024-01-07 02:28:09', null),
|
||||
(21, '角色管理', 'SysRole', 0, 2, null, 'sys-role', 1, '/admin/role/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:25:45', null),
|
||||
(22, '新增', '', 0, 0, null, null, 2, null, 'sys:role:add', 1, 1, 1, null, 21, '2024-01-07 11:58:37', null),
|
||||
(23, '编辑', '', 0, 0, null, null, 2, null, 'sys:role:edit', 1, 1, 1, null, 21, '2024-01-07 11:58:52', null),
|
||||
(24, '删除', '', 0, 0, null, null, 2, null, 'sys:role:del', 1, 1, 1, null, 21, '2024-01-07 11:59:07', null),
|
||||
(25, '编辑角色菜单', '', 0, 0, null, null, 2, null, 'sys:role:menu:edit', 1, 1, 1, null, 21, '2024-01-07 01:59:39', null),
|
||||
(26, '菜单管理', 'SysMenu', 0, 2, null, 'sys-menu', 1, '/admin/menu/index.vue', null, 1, 1, 1, null, 9, '2023-07-27 19:45:29', null),
|
||||
(27, '新增', '', 0, 0, null, null, 2, null, 'sys:menu:add', 1, 1, 1, null, 26, '2024-01-07 12:01:24', null),
|
||||
(28, '编辑', '', 0, 0, null, null, 2, null, 'sys:menu:edit', 1, 1, 1, null, 26, '2024-01-07 12:01:34', null),
|
||||
(29, '删除', '', 0, 0, null, null, 2, null, 'sys:menu:del', 1, 1, 1, null, 26, '2024-01-07 12:01:48', null),
|
||||
(30, '系统监控', 'monitor', 0, 88, 'IconComputer', 'monitor', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:27:08', null),
|
||||
(31, 'Redis监控', 'Redis', 0, 0, null, 'redis', 1, '/monitor/redis/index.vue', 'sys:monitor:redis', 1, 1, 1, null, 30, '2023-07-27 19:28:03', null),
|
||||
(32, '服务器监控', 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', 'sys:monitor:server', 1, 1, 1, null, 30, '2023-07-27 19:28:29', null),
|
||||
(33, '系统自动化', 'automation', 0, 777, 'IconCodeSquare', 'automation', 0, null, null, 1, 1, 1, null, null, '2024-07-27 02:06:20', '2024-07-27 02:18:52'),
|
||||
(34, '代码生成', 'CodeGenerator', 0, 0, null, 'code-generator', 1, '/automation/generator/index.vue', null, 1, 1, 1, null, 33, '2024-07-27 12:24:54', null),
|
||||
(35, '导入', '', 0, 0, null, null, 2, null, 'gen:code:import', 1, 1, 1, null, 34, '2024-08-04 12:49:58', null),
|
||||
(36, '新增业务', '', 0, 0, null, null, 2, null, 'gen:code:business:add', 1, 1, 1, null, 34, '2024-08-04 12:51:29', null),
|
||||
(37, '编辑业务', '', 0, 0, null, null, 2, null, 'gen:code:business:edit', 1, 1, 1, null, 34, '2024-08-04 12:51:45', null),
|
||||
(48, '删除业务', '', 0, 0, null, null, 2, null, 'gen:code:business:del', 1, 1, 1, null, 34, '2024-08-04 12:52:05', null),
|
||||
(49, '新增模型', '', 0, 0, null, null, 2, null, 'gen:code:model:add', 1, 1, 1, null, 34, '2024-08-04 12:52:28', null),
|
||||
(50, '编辑模型', '', 0, 0, null, null, 2, null, 'gen:code:model:edit', 1, 1, 1, null, 34, '2024-08-04 12:52:45', null),
|
||||
(51, '删除模型', '', 0, 0, null, null, 2, null, 'gen:code:model:del', 1, 1, 1, null, 34, '2024-08-04 12:52:59', null),
|
||||
(52, '生成', '', 0, 0, null, null, 2, null, 'gen:code:generate', 1, 1, 1, null, 34, '2024-08-04 12:55:03', null),
|
||||
(53, 'GitHub', 'github', 0, 8888, 'IconGithub', 'https://github.com/wu-clan', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:32:46', null),
|
||||
(54, '赞助', 'sponsor', 0, 9999, 'IconFire', 'https://wu-clan.github.io/sponsor/', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:39:57', null);
|
||||
(4, '日志', 'log', 0, 66, 'IconBug', 'log', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:19:59', null),
|
||||
(5, '登录日志', 'Login', 0, 0, null, 'login', 1, '/log/login/index.vue', null, 1, 1, 1, null, 4, '2023-07-27 19:20:56', null),
|
||||
(6, '操作日志', 'Opera', 0, 0, null, 'opera', 1, '/log/opera/index.vue', null, 1, 1, 1, null, 4, '2023-07-27 19:21:28', null),
|
||||
(7, '系统管理', 'admin', 0, 6, 'IconSettings', 'admin', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:23:00', null),
|
||||
(8, '部门管理', 'SysDept', 0, 0, null, 'sys-dept', 1, '/admin/dept/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:23:42', null),
|
||||
(9, '新增', '', 0, 0, null, null, 2, null, 'sys:dept:add', 1, 1, 1, null, 8, '2024-01-07 11:37:00', null),
|
||||
(10, '编辑', '', 0, 0, null, null, 2, null, 'sys:dept:edit', 1, 1, 1, null, 8, '2024-01-07 11:37:29', null),
|
||||
(11, '删除', '', 0, 0, null, null, 2, null, 'sys:dept:del', 1, 1, 1, null, 8, '2024-01-07 11:37:44', null),
|
||||
(12, 'API管理', 'SysApi', 0, 1, null, 'sys-api', 1, '/admin/api/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:24:12', null),
|
||||
(13, '新增', '', 0, 0, null, null, 2, null, 'sys:api:add', 1, 1, 1, null, 12, '2024-01-07 11:57:09', null),
|
||||
(14, '编辑', '', 0, 0, null, null, 2, null, 'sys:api:edit', 1, 1, 1, null, 12, '2024-01-07 11:57:44', null),
|
||||
(15, '删除', '', 0, 0, null, null, 2, null, 'sys:api:del', 1, 1, 1, null, 12, '2024-01-07 11:57:56', null),
|
||||
(16, '用户管理', 'SysUser', 0, 0, null, 'sys-user', 1, '/admin/user/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:25:13', null),
|
||||
(17, '编辑用户角色', '', 0, 0, null, null, 2, null, 'sys:user:role:edit', 1, 1, 1, null, 16, '2024-01-07 12:04:20', null),
|
||||
(18, '注销', '', 0, 0, null, null, 2, null, 'sys:user:del', 1, 1, 1, '用户注销 != 用户登出,注销之后用户将从数据库删除', 16, '2024-01-07 02:28:09', null),
|
||||
(19, '角色管理', 'SysRole', 0, 2, null, 'sys-role', 1, '/admin/role/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:25:45', null),
|
||||
(20, '新增', '', 0, 0, null, null, 2, null, 'sys:role:add', 1, 1, 1, null, 19, '2024-01-07 11:58:37', null),
|
||||
(21, '编辑', '', 0, 0, null, null, 2, null, 'sys:role:edit', 1, 1, 1, null, 19, '2024-01-07 11:58:52', null),
|
||||
(22, '删除', '', 0, 0, null, null, 2, null, 'sys:role:del', 1, 1, 1, null, 19, '2024-01-07 11:59:07', null),
|
||||
(23, '编辑角色菜单', '', 0, 0, null, null, 2, null, 'sys:role:menu:edit', 1, 1, 1, null, 19, '2024-01-07 01:59:39', null),
|
||||
(24, '菜单管理', 'SysMenu', 0, 2, null, 'sys-menu', 1, '/admin/menu/index.vue', null, 1, 1, 1, null, 7, '2023-07-27 19:45:29', null),
|
||||
(25, '新增', '', 0, 0, null, null, 2, null, 'sys:menu:add', 1, 1, 1, null, 24, '2024-01-07 12:01:24', null),
|
||||
(26, '编辑', '', 0, 0, null, null, 2, null, 'sys:menu:edit', 1, 1, 1, null, 24, '2024-01-07 12:01:34', null),
|
||||
(27, '删除', '', 0, 0, null, null, 2, null, 'sys:menu:del', 1, 1, 1, null, 24, '2024-01-07 12:01:48', null),
|
||||
(28, '系统监控', 'monitor', 0, 88, 'IconComputer', 'monitor', 0, null, null, 1, 1, 1, null, null, '2023-07-27 19:27:08', null),
|
||||
(29, 'Redis监控', 'Redis', 0, 0, null, 'redis', 1, '/monitor/redis/index.vue', 'sys:monitor:redis', 1, 1, 1, null, 28, '2023-07-27 19:28:03', null),
|
||||
(30, '服务器监控', 'Server', 0, 0, null, 'server', 1, '/monitor/server/index.vue', 'sys:monitor:server', 1, 1, 1, null, 28, '2023-07-27 19:28:29', null),
|
||||
(31, '系统自动化', 'automation', 0, 777, 'IconCodeSquare', 'automation', 0, null, null, 1, 1, 1, null, null, '2024-07-27 02:06:20', '2024-07-27 02:18:52'),
|
||||
(32, '代码生成', 'CodeGenerator', 0, 0, null, 'code-generator', 1, '/automation/generator/index.vue', null, 1, 1, 1, null, 31, '2024-07-27 12:24:54', null),
|
||||
(33, '导入', '', 0, 0, null, null, 2, null, 'gen:code:import', 1, 1, 1, null, 31, '2024-08-04 12:49:58', null),
|
||||
(34, '新增业务', '', 0, 0, null, null, 2, null, 'gen:code:business:add', 1, 1, 1, null, 31, '2024-08-04 12:51:29', null),
|
||||
(35, '编辑业务', '', 0, 0, null, null, 2, null, 'gen:code:business:edit', 1, 1, 1, null, 31, '2024-08-04 12:51:45', null),
|
||||
(36, '删除业务', '', 0, 0, null, null, 2, null, 'gen:code:business:del', 1, 1, 1, null, 31, '2024-08-04 12:52:05', null),
|
||||
(37, '新增模型', '', 0, 0, null, null, 2, null, 'gen:code:model:add', 1, 1, 1, null, 31, '2024-08-04 12:52:28', null),
|
||||
(38, '编辑模型', '', 0, 0, null, null, 2, null, 'gen:code:model:edit', 1, 1, 1, null, 31, '2024-08-04 12:52:45', null),
|
||||
(39, '删除模型', '', 0, 0, null, null, 2, null, 'gen:code:model:del', 1, 1, 1, null, 31, '2024-08-04 12:52:59', null),
|
||||
(40, '生成', '', 0, 0, null, null, 2, null, 'gen:code:generate', 1, 1, 1, null, 31, '2024-08-04 12:55:03', null),
|
||||
(41, 'GitHub', 'github', 0, 8888, 'IconGithub', 'https://github.com/wu-clan', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:32:46', null),
|
||||
(42, '赞助', 'sponsor', 0, 9999, 'IconFire', 'https://wu-clan.github.io/sponsor/', 0, null, null, 1, 1, 1, null, null, '2024-07-27 12:39:57', null);
|
||||
|
||||
INSERT INTO fba.sys_role (id, name, data_scope, status, remark, created_time, updated_time)
|
||||
VALUES (1, 'test', 2, 1, null, '2023-06-26 17:13:45', null);
|
||||
|
@ -60,7 +60,7 @@ async def create_{{ table_name_en }}(obj: Create{{ schema_name }}Param) -> Respo
|
||||
async def update_{{ table_name_en }}(pk: Annotated[int, Path(...)], obj: Update{{ schema_name }}Param) -> ResponseModel:
|
||||
count = await {{ table_name_en }}_service.update(pk=pk, obj=obj)
|
||||
if count > 0:
|
||||
return await response_base.success()
|
||||
return response_base.success()
|
||||
return response_base.fail()
|
||||
|
||||
|
||||
@ -75,5 +75,5 @@ async def update_{{ table_name_en }}(pk: Annotated[int, Path(...)], obj: Update{
|
||||
async def delete_{{ table_name_en }}(pk: Annotated[list[int], Query(...)]) -> ResponseModel:
|
||||
count = await {{ table_name_en }}_service.delete(pk=pk)
|
||||
if count > 0:
|
||||
return await response_base.success()
|
||||
return response_base.success()
|
||||
return response_base.fail()
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from uuid import UUID
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
@ -19,10 +21,13 @@ class {{ table_name_class }}({% if have_datetime_column %}Base{% else %}MappedBa
|
||||
{%- if model.is_nullable %} Mapped[{{ model.pd_type }} | None]
|
||||
{%- else %} Mapped[{{ model.pd_type }}]
|
||||
{%- endif %} = mapped_column(
|
||||
{%- if model.type == 'VARCHAR' -%}
|
||||
{%- if model.type in ['NVARCHAR', 'String', 'Unicode', 'VARCHAR'] -%}
|
||||
sa.String({{ model.length }})
|
||||
{%- else -%}
|
||||
{%- elif model.type in ['BIT', 'ENUM', 'LONGBLOB', 'LONGTEXT', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'SET',
|
||||
'TINYBLOB', 'TINYINT', 'TINYTEXT', 'YEAR'] -%}
|
||||
mysql.{{ model.type }}()
|
||||
{%- else -%}
|
||||
sa.{{ model.type }}()
|
||||
{%- endif -%}, default=
|
||||
{%- if model.is_nullable and model.default == None -%}
|
||||
None
|
||||
@ -44,7 +49,7 @@ class {{ table_name_class }}({% if have_datetime_column %}Base{% else %}MappedBa
|
||||
{}
|
||||
{%- elif model.pd_type == 'date' or model.pd_type == 'datetime' -%}
|
||||
timezone.now()
|
||||
{%- elif model.pd_type == 'List[str]' -%}
|
||||
{%- elif model.pd_type == 'list[str]' -%}
|
||||
()
|
||||
{%- else -%}
|
||||
''
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from backend.common.enums import GenModelColumnType
|
||||
from backend.common.enums import GenModelMySQLColumnType
|
||||
|
||||
|
||||
def sql_type_to_sqlalchemy(typing: str) -> str:
|
||||
@ -10,43 +10,9 @@ def sql_type_to_sqlalchemy(typing: str) -> str:
|
||||
:param typing:
|
||||
:return:
|
||||
"""
|
||||
type_mapping = {
|
||||
GenModelColumnType.BIGINT: 'BIGINT',
|
||||
GenModelColumnType.BINARY: 'BINARY',
|
||||
GenModelColumnType.BIT: 'BIT',
|
||||
GenModelColumnType.BLOB: 'BLOG',
|
||||
GenModelColumnType.BOOL: 'BOOLEAN',
|
||||
GenModelColumnType.BOOLEAN: 'BOOLEAN',
|
||||
GenModelColumnType.CHAR: 'CHAR',
|
||||
GenModelColumnType.DATE: 'DATE',
|
||||
GenModelColumnType.DATETIME: 'DATETIME',
|
||||
GenModelColumnType.DECIMAL: 'DECIMAL',
|
||||
GenModelColumnType.DOUBLE: 'DOUBLE',
|
||||
GenModelColumnType.ENUM: 'ENUM',
|
||||
GenModelColumnType.FLOAT: 'FLOAT',
|
||||
GenModelColumnType.INT: 'INT',
|
||||
GenModelColumnType.INTEGER: 'INTEGER',
|
||||
GenModelColumnType.JSON: 'JSON',
|
||||
GenModelColumnType.LONGBLOB: 'LONGBLOB',
|
||||
GenModelColumnType.LONGTEXT: 'LONGTEXT',
|
||||
GenModelColumnType.MEDIUMBLOB: 'MEDIUMBLOB',
|
||||
GenModelColumnType.MEDIUMINT: 'MEDIUMINT',
|
||||
GenModelColumnType.MEDIUMTEXT: 'MEDIUMTEXT',
|
||||
GenModelColumnType.NUMERIC: 'NUMERIC',
|
||||
GenModelColumnType.SET: 'SET',
|
||||
GenModelColumnType.SMALLINT: 'SMALLINT',
|
||||
GenModelColumnType.REAL: 'REAL',
|
||||
GenModelColumnType.TEXT: 'TEXT',
|
||||
GenModelColumnType.TIME: 'TIME',
|
||||
GenModelColumnType.TIMESTAMP: 'TIMESTAMP',
|
||||
GenModelColumnType.TINYBLOB: 'TINYBLOB',
|
||||
GenModelColumnType.TINYINT: 'TINYINT',
|
||||
GenModelColumnType.TINYTEXT: 'TINYTEXT',
|
||||
GenModelColumnType.VARBINARY: 'VARBINARY',
|
||||
GenModelColumnType.VARCHAR: 'VARCHAR',
|
||||
GenModelColumnType.YEAR: 'YEAR',
|
||||
}
|
||||
return type_mapping.get(typing, 'VARCHAR')
|
||||
if typing in GenModelMySQLColumnType.get_member_keys():
|
||||
return typing
|
||||
return 'String'
|
||||
|
||||
|
||||
def sql_type_to_pydantic(typing: str) -> str:
|
||||
@ -56,40 +22,7 @@ def sql_type_to_pydantic(typing: str) -> str:
|
||||
:param typing:
|
||||
:return:
|
||||
"""
|
||||
type_mapping = {
|
||||
GenModelColumnType.BIGINT: 'int',
|
||||
GenModelColumnType.BINARY: 'bytes',
|
||||
GenModelColumnType.BIT: 'bool',
|
||||
GenModelColumnType.BLOB: 'bytes',
|
||||
GenModelColumnType.BOOL: 'bool',
|
||||
GenModelColumnType.BOOLEAN: 'bool',
|
||||
GenModelColumnType.CHAR: 'str',
|
||||
GenModelColumnType.DATE: 'date',
|
||||
GenModelColumnType.DATETIME: 'datetime',
|
||||
GenModelColumnType.DECIMAL: 'Decimal',
|
||||
GenModelColumnType.DOUBLE: 'float',
|
||||
GenModelColumnType.ENUM: 'Enum',
|
||||
GenModelColumnType.FLOAT: 'float',
|
||||
GenModelColumnType.INT: 'int',
|
||||
GenModelColumnType.INTEGER: 'int',
|
||||
GenModelColumnType.JSON: 'dict',
|
||||
GenModelColumnType.LONGBLOB: 'bytes',
|
||||
GenModelColumnType.LONGTEXT: 'str',
|
||||
GenModelColumnType.MEDIUMBLOB: 'bytes',
|
||||
GenModelColumnType.MEDIUMINT: 'int',
|
||||
GenModelColumnType.MEDIUMTEXT: 'str',
|
||||
GenModelColumnType.NUMERIC: 'NUMERIC',
|
||||
GenModelColumnType.SET: 'List[str]',
|
||||
GenModelColumnType.SMALLINT: 'int',
|
||||
GenModelColumnType.REAL: 'float',
|
||||
GenModelColumnType.TEXT: 'str',
|
||||
GenModelColumnType.TIME: 'time',
|
||||
GenModelColumnType.TIMESTAMP: 'datetime',
|
||||
GenModelColumnType.TINYBLOB: 'bytes',
|
||||
GenModelColumnType.TINYINT: 'int',
|
||||
GenModelColumnType.TINYTEXT: 'str',
|
||||
GenModelColumnType.VARBINARY: 'bytes',
|
||||
GenModelColumnType.VARCHAR: 'str',
|
||||
GenModelColumnType.YEAR: 'int',
|
||||
}
|
||||
return type_mapping.get(typing, 'str')
|
||||
try:
|
||||
return GenModelMySQLColumnType[typing].value
|
||||
except KeyError:
|
||||
return 'str'
|
||||
|
Reference in New Issue
Block a user