Optimize code generation data processing (#1020)

* Optimize code generation data processing

* Add SQL script generation

* Update code gen table scripts

* Update types

* Fix model jinja and type conversion
This commit is contained in:
Wu Clan
2026-01-20 18:27:42 +08:00
committed by GitHub
parent b2785dd46f
commit 1a6aba6105
22 changed files with 467 additions and 298 deletions
+107 -70
View File
@@ -1,6 +1,6 @@
from collections.abc import Sequence
from sqlalchemy import Row, RowMapping, text
from sqlalchemy import RowMapping, text
from sqlalchemy.ext.asyncio import AsyncSession
from backend.common.enums import DataBaseType
@@ -21,57 +21,75 @@ class CRUDGen:
"""
if DataBaseType.mysql == settings.DATABASE_TYPE:
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_schema = :table_schema;
SELECT TABLE_NAME AS TABLE_NAME,
table_comment AS table_comment
FROM
information_schema.TABLES
WHERE
TABLE_NAME NOT LIKE'sys_gen_%'
AND table_schema = :table_schema;
"""
stmt = text(sql).bindparams(table_schema=table_schema)
else:
sql = """
SELECT c.relname AS table_name, obj_description(c.oid) AS table_comment
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname = 'public' -- schema 通常是 'public'
AND c.relname NOT LIKE 'sys_gen_%';
SELECT
c.relname AS TABLE_NAME,
obj_description (c.OID) AS table_comment
FROM
pg_class c
LEFT JOIN pg_namespace n ON n.OID = c.relnamespace
WHERE
c.relkind = 'r'
AND c.relname NOT LIKE'sys_gen_%'
AND n.nspname = :table_schema;
"""
stmt = text(sql)
stmt = text(sql).bindparams(table_schema='public')
result = await db.execute(stmt)
return result.mappings().all()
@staticmethod
async def get_table(db: AsyncSession, table_name: str) -> Row[tuple]:
async def get_table(db: AsyncSession, table_schema: str, table_name: str) -> RowMapping | None:
"""
获取表信息
:param db: 数据库会话
:param table_schema: 数据库 schema 名称
:param table_name: 表名
:return:
"""
if DataBaseType.mysql == settings.DATABASE_TYPE:
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;
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
AND table_schema = :table_schema;
"""
stmt = text(sql).bindparams(table_schema=table_schema, table_name=table_name)
else:
sql = """
SELECT c.relname AS table_name, obj_description(c.oid) AS table_comment
FROM pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname = 'public' -- schema 通常是 'public'
AND c.relname = :table_name
AND c.relname NOT LIKE 'sys_gen_%';
SELECT
c.relname AS table_name,
obj_description (c.OID) AS table_comment
FROM
pg_class c
LEFT JOIN pg_namespace n ON n.OID = c.relnamespace
WHERE
c.relkind = 'r'
AND c.relname NOT LIKE'sys_gen_%'
AND c.relname = :table_name
AND n.nspname = :table_schema;
"""
stmt = text(sql).bindparams(table_name=table_name)
stmt = text(sql).bindparams(table_schema='public', table_name=table_name)
result = await db.execute(stmt)
return result.fetchone()
row = result.fetchone()
return row._mapping if row else None
@staticmethod
async def get_all_columns(db: AsyncSession, table_schema: str, table_name: str) -> Sequence[Row[tuple]]:
async def get_all_columns(db: AsyncSession, table_schema: str, table_name: str) -> Sequence[RowMapping]:
"""
获取所有列信息
@@ -82,54 +100,73 @@ class CRUDGen:
"""
if DataBaseType.mysql == settings.DATABASE_TYPE:
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;
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
COLUMN_NAME <> 'id'
AND COLUMN_NAME <> 'created_time'
AND COLUMN_NAME <> 'updated_time'
AND TABLE_NAME = :table_name
AND table_schema = :table_schema
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)
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
a.attnum > 0
AND NOT a.attisdropped
AND a.attname <> 'id'
AND a.attname <> 'created_time'
AND a.attname <> 'updated_time'
AND t.relname = :table_name
AND n.nspname = :table_schema
ORDER BY
sort;
""" # noqa: E501
stmt = text(sql).bindparams(table_schema='public', table_name=table_name)
result = await db.execute(stmt)
return result.fetchall()
return result.mappings().all()
gen_dao: CRUDGen = CRUDGen()