Update the code generator to plugin (#578)

* Update the code generator to plugin

* Fix get all tables return type
This commit is contained in:
Wu Clan
2025-04-17 11:06:43 +08:00
committed by GitHub
parent 1cc020efdd
commit fc34c98f0a
40 changed files with 211 additions and 205 deletions
@@ -0,0 +1,2 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
@@ -0,0 +1,130 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy import Row, text
from sqlalchemy.ext.asyncio import AsyncSession
from backend.core.conf import settings
class CRUDGen:
"""代码生成 CRUD 类"""
@staticmethod
async def get_all_tables(db: AsyncSession, table_schema: str) -> Sequence[str]:
"""
获取所有表名
:param db: 数据库会话
:param table_schema: 数据库 schema 名称
:return:
"""
if settings.DATABASE_TYPE == 'mysql':
sql = """
SELECT table_name AS table_name FROM information_schema.tables
WHERE table_name NOT LIKE 'sys_gen_%'
AND table_schema = :table_schema;
"""
else:
sql = """
SELECT table_name AS table_name FROM information_schema.tables
WHERE table_name NOT LIKE 'sys_gen_%'
AND table_catalog = :table_schema
AND table_schema = 'public'; -- schema 通常是 'public'
"""
stmt = text(sql).bindparams(table_schema=table_schema)
result = await db.execute(stmt)
return result.scalars().all()
@staticmethod
async def get_table(db: AsyncSession, table_name: str) -> Row[tuple]:
"""
获取表信息
:param db: 数据库会话
:param table_name: 表名
:return:
"""
if settings.DATABASE_TYPE == 'mysql':
sql = """
SELECT table_name AS table_name, table_comment AS table_comment FROM information_schema.tables
WHERE table_name NOT LIKE 'sys_gen_%'
AND table_name = :table_name;
"""
else:
sql = """
SELECT t.tablename AS table_name,
pg_catalog.obj_description(t.tablename::regclass, 'pg_class') AS table_comment
FROM pg_tables t
WHERE t.tablename NOT LIKE 'sys_gen_%'
AND t.tablename = :table_name
AND t.schemaname = 'public'; -- schema 通常是 'public'
"""
stmt = text(sql).bindparams(table_name=table_name)
result = await db.execute(stmt)
return result.fetchone()
@staticmethod
async def get_all_columns(db: AsyncSession, table_schema: str, table_name: str) -> Sequence[Row[tuple]]:
"""
获取所有列信息
:param db: 数据库会话
:param table_schema: 数据库 schema 名称
:param table_name: 表名
:return:
"""
if settings.DATABASE_TYPE == 'mysql':
sql = """
SELECT column_name AS column_name,
CASE WHEN column_key = 'PRI' THEN 1 ELSE 0 END AS is_pk,
CASE WHEN is_nullable = 'NO' OR column_key = 'PRI' THEN 0 ELSE 1 END AS is_nullable,
ordinal_position AS sort, column_comment AS column_comment,
column_type AS column_type FROM information_schema.columns
WHERE table_schema = :table_schema
AND table_name = :table_name
AND column_name <> 'id'
AND column_name <> 'created_time'
AND column_name <> 'updated_time'
ORDER BY sort;
"""
stmt = text(sql).bindparams(table_schema=table_schema, table_name=table_name)
else:
sql = """
SELECT a.attname AS column_name,
CASE WHEN EXISTS (
SELECT 1
FROM pg_constraint c
WHERE c.conrelid = t.oid
AND c.contype = 'p'
AND a.attnum = ANY(c.conkey)
) THEN 1 ELSE 0 END AS is_pk,
CASE WHEN a.attnotnull OR EXISTS (
SELECT 1
FROM pg_constraint c
WHERE c.conrelid = t.oid
AND c.contype = 'p'
AND a.attnum = ANY(c.conkey)
) THEN 0 ELSE 1 END AS is_nullable,
a.attnum AS sort,
col_description(t.oid, a.attnum) AS column_comment,
pg_catalog.format_type(a.atttypid, a.atttypmod) AS column_type
FROM pg_attribute a
JOIN pg_class t ON a.attrelid = t.oid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE n.nspname = 'public' -- 根据你的实际情况修改 schema 名称,通常是 'public'
AND t.relname = :table_name
AND a.attnum > 0
AND NOT a.attisdropped
AND a.attname <> 'id'
AND a.attname <> 'created_time'
AND a.attname <> 'updated_time'
ORDER BY sort;
"""
stmt = text(sql).bindparams(table_name=table_name)
result = await db.execute(stmt)
return result.fetchall()
gen_dao: CRUDGen = CRUDGen()
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy_crud_plus import CRUDPlus
from backend.plugin.code_generator.model import GenBusiness
from backend.plugin.code_generator.schema.gen_business import CreateGenBusinessParam, UpdateGenBusinessParam
class CRUDGenBusiness(CRUDPlus[GenBusiness]):
"""代码生成业务 CRUD 类"""
async def get(self, db: AsyncSession, pk: int) -> GenBusiness | None:
"""
获取代码生成业务
:param db: 数据库会话
:param pk: 代码生成业务 ID
:return:
"""
return await self.select_model(db, pk)
async def get_by_name(self, db: AsyncSession, name: str) -> GenBusiness | None:
"""
通过 name 获取代码生成业务
:param db: 数据库会话
:param name: 表名
:return:
"""
return await self.select_model_by_column(db, table_name_en=name)
async def get_all(self, db: AsyncSession) -> Sequence[GenBusiness]:
"""
获取所有代码生成业务
:param db: 数据库会话
:return:
"""
return await self.select_models(db)
async def create(self, db: AsyncSession, obj: CreateGenBusinessParam) -> None:
"""
创建代码生成业务
:param db: 数据库会话
:param obj: 创建代码生成业务参数
:return:
"""
await self.create_model(db, obj)
async def update(self, db: AsyncSession, pk: int, obj: UpdateGenBusinessParam) -> int:
"""
更新代码生成业务
:param db: 数据库会话
:param pk: 代码生成业务 ID
:param obj: 更新代码生成业务参数
:return:
"""
return await self.update_model(db, pk, obj)
async def delete(self, db: AsyncSession, pk: int) -> int:
"""
删除代码生成业务
:param db: 数据库会话
:param pk: 代码生成业务 ID
:return:
"""
return await self.delete_model(db, pk)
gen_business_dao: CRUDGenBusiness = CRUDGenBusiness(GenBusiness)
@@ -0,0 +1,69 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy_crud_plus import CRUDPlus
from backend.plugin.code_generator.model import GenModel
from backend.plugin.code_generator.schema.gen_model import CreateGenModelParam, UpdateGenModelParam
class CRUDGenModel(CRUDPlus[GenModel]):
"""代码生成模型 CRUD 类"""
async def get(self, db: AsyncSession, pk: int) -> GenModel | None:
"""
获取代码生成模型列
:param db: 数据库会话
:param pk: 代码生成模型 ID
:return:
"""
return await self.select_model(db, pk)
async def get_all_by_business(self, db: AsyncSession, business_id: int) -> Sequence[GenModel]:
"""
获取所有代码生成模型列
:param db: 数据库会话
:param business_id: 业务 ID
:return:
"""
return await self.select_models_order(db, sort_columns='sort', gen_business_id=business_id)
async def create(self, db: AsyncSession, obj: CreateGenModelParam, pd_type: str | None) -> None:
"""
创建代码生成模型
:param db: 数据库会话
:param obj: 创建代码生成模型参数
:param pd_type: Pydantic 类型
:return:
"""
await self.create_model(db, obj, pd_type=pd_type)
async def update(self, db: AsyncSession, pk: int, obj: UpdateGenModelParam, pd_type: str | None) -> int:
"""
更新代码生成模型
:param db: 数据库会话
:param pk: 代码生成模型 ID
:param obj: 更新代码生成模型参数
:param pd_type: Pydantic 类型
:return:
"""
return await self.update_model(db, pk, obj, pd_type=pd_type)
async def delete(self, db: AsyncSession, pk: int) -> int:
"""
删除代码生成模型
:param db: 数据库会话
:param pk: 代码生成模型 ID
:return:
"""
return await self.delete_model(db, pk)
gen_model_dao: CRUDGenModel = CRUDGenModel(GenModel)