mirror of
https://github.com/fastapi-practices/fastapi-best-architecture.git
synced 2026-09-21 21:15:13 +00:00
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:
@@ -8,7 +8,7 @@ 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{{ class_name }}(CRUDPlus[{{ schema_name }}]):
|
||||
class CRUD{{ class_name }}(CRUDPlus[{{ class_name }}]):
|
||||
async def get(self, db: AsyncSession, pk: int) -> {{ class_name }} | None:
|
||||
"""
|
||||
获取{{ doc_comment }}
|
||||
|
||||
@@ -5,29 +5,48 @@
|
||||
'HSTORE', 'INET', 'INT4MULTIRANGE', 'INT4RANGE', 'INT8MULTIRANGE', 'INT8RANGE', 'INTERVAL', 'JSONB', 'JSONPATH',
|
||||
'MACADDR', 'MACADDR8', 'MONEY', 'NUMMULTIRANGE', 'NUMRANGE', 'OID', 'REGCLASS', 'REGCONFIG', 'TSMULTIRANGE', 'TSQUERY',
|
||||
'TSRANGE', 'TSTZMULTIRANGE', 'TSTZRANGE', 'TSVECTOR'] %}
|
||||
{% if default_datetime_column %}
|
||||
from datetime import datetime
|
||||
{% set FACTORY_TYPES = ['dict', 'list', 'list[str]', 'list[int]'] %}
|
||||
{% set pd_types = models|map(attribute='pd_type')|list %}
|
||||
{% set NEED_MYSQL_DIALECT = database_type == 'mysql' and model_types|select('in', MYSQL_TYPES)|list|length > 0 %}
|
||||
{% set NEED_PGSQL_DIALECT = database_type == 'postgresql' and model_types|select('in', POSTGRESQL_TYPES)|list|length > 0 %}
|
||||
{% set NEED_DATE = 'date' in pd_types %}
|
||||
{% set NEED_DATETIME = datetime_mixin or 'datetime' in pd_types %}
|
||||
{% set NEED_UNIVERSAL_TEXT = 'TEXT' in model_types or 'Text' in model_types or 'LONGTEXT' in model_types %}
|
||||
{% set NEED_TIMEZONE = 'TIMESTAMP' in model_types or 'DateTime' in model_types or 'TIMESTAMP WITHOUT TIME ZONE' in model_types or 'TIMESTAMP WITH TIME ZONE' in model_types %}
|
||||
{% if NEED_DATETIME or NEED_DATE %}
|
||||
from datetime import {% if NEED_DATETIME %}datetime{% endif %}{% if NEED_DATE %}{% if NEED_DATETIME %}, {% endif %}date{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% if model_types|select('in', DECIMAL_TYPES)|first %}
|
||||
from decimal import Decimal
|
||||
|
||||
{% endif %}
|
||||
{% if 'Uuid' in model_types or 'UUID' in model_types %}
|
||||
from uuid import UUID
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
import sqlalchemy as sa
|
||||
|
||||
{% if database_type == 'mysql' -%}
|
||||
{% if NEED_MYSQL_DIALECT %}
|
||||
from sqlalchemy.dialects import mysql
|
||||
{% else -%}
|
||||
{% endif %}
|
||||
{% if NEED_PGSQL_DIALECT %}
|
||||
from sqlalchemy.dialects import postgresql
|
||||
{% endif -%}
|
||||
{% endif %}
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from backend.common.model import {% if default_datetime_column %}Base{% else %}DataClassBase{% endif %}, id_key
|
||||
from backend.common.model import {% if datetime_mixin %}Base{% else %}DataClassBase{% endif %}, id_key
|
||||
{%- if NEED_UNIVERSAL_TEXT or NEED_TIMEZONE %}, {% endif %}
|
||||
{%- if NEED_UNIVERSAL_TEXT %}UniversalText{% endif %}
|
||||
{%- if NEED_UNIVERSAL_TEXT and NEED_TIMEZONE %}, {% endif %}
|
||||
{%- if NEED_TIMEZONE %}TimeZone{% endif %}
|
||||
|
||||
{% if NEED_TIMEZONE %}
|
||||
from backend.utils.timezone import timezone
|
||||
{% endif %}
|
||||
|
||||
|
||||
class {{ class_name }}({% if default_datetime_column %}Base{% else %}DataClassBase{% endif %}):
|
||||
class {{ class_name }}({% if datetime_mixin %}Base{% else %}DataClassBase{% endif %}):
|
||||
"""{{ table_comment }}"""
|
||||
|
||||
__tablename__ = '{{ table_name }}'
|
||||
@@ -38,41 +57,36 @@ class {{ class_name }}({% if default_datetime_column %}Base{% else %}DataClassBa
|
||||
{%- if model.is_nullable %} Mapped[{{ model.pd_type }} | None]
|
||||
{%- else %} Mapped[{{ model.pd_type }}]
|
||||
{%- endif %} = mapped_column(
|
||||
{%- if model.type in ['NVARCHAR', 'String', 'Unicode', 'VARCHAR'] -%}
|
||||
{%- if model.type in ['TEXT', 'Text', 'LONGTEXT'] -%}
|
||||
UniversalText
|
||||
{%- elif model.type in ['TIMESTAMP', 'DateTime', 'TIMESTAMP WITHOUT TIME ZONE', 'TIMESTAMP WITH TIME ZONE'] -%}
|
||||
TimeZone
|
||||
{%- elif model.type in ['NVARCHAR', 'String', 'Unicode', 'VARCHAR', 'CHARACTER VARYING'] -%}
|
||||
sa.String({{ model.length }})
|
||||
{%- elif database_type == 'mysql' and model.type in MYSQL_TYPES -%}
|
||||
mysql.{{ model.type }}()
|
||||
mysql.{{ model.type|sqlalchemy_type }}()
|
||||
{%- elif database_type == 'postgresql' and model.type in POSTGRESQL_TYPES -%}
|
||||
{%- else -%}
|
||||
sa.{{ model.type }}()
|
||||
{%- endif -%}, default=
|
||||
{%- if model.is_nullable and model.default == None -%}
|
||||
None
|
||||
{%- else -%}
|
||||
{%- if model.default != None -%}
|
||||
'{{ model.default }}'
|
||||
{%- if model.type == 'ARRAY' -%}
|
||||
postgresql.ARRAY(sa.String)
|
||||
{%- else -%}
|
||||
{%- if model.pd_type == 'str' -%}
|
||||
''
|
||||
{%- elif model.pd_type == 'int' -%}
|
||||
0
|
||||
{%- elif model.pd_type == 'bytes' -%}
|
||||
b''
|
||||
{%- elif model.pd_type == 'bool' -%}
|
||||
True
|
||||
{%- elif model.pd_type == 'float' -%}
|
||||
0.0
|
||||
{%- elif model.pd_type == 'dict' -%}
|
||||
{}
|
||||
{%- elif model.pd_type == 'date' or model.pd_type == 'datetime' -%}
|
||||
timezone.now()
|
||||
{%- elif model.pd_type == 'list[str]' -%}
|
||||
()
|
||||
{%- else -%}
|
||||
''
|
||||
{%- endif -%}
|
||||
postgresql.{{ model.type|sqlalchemy_type }}()
|
||||
{%- endif -%}
|
||||
{%- endif -%}{% if model.sort != 0 %}, sort_order={{ model.sort }}{% endif %}, comment=
|
||||
{%- else -%}
|
||||
sa.{{ model.type|sqlalchemy_type }}()
|
||||
{%- endif -%},
|
||||
{%- if model.is_nullable and model.default == None %} default=None
|
||||
{%- elif model.default != None %} default='{{ model.default }}'
|
||||
{%- elif model.pd_type in FACTORY_TYPES %} default_factory={{ model.pd_type.split('[')[0] }}
|
||||
{%- elif model.pd_type == 'str' %} default=''
|
||||
{%- elif model.pd_type == 'int' %} default=0
|
||||
{%- elif model.pd_type == 'bytes' %} default=b''
|
||||
{%- elif model.pd_type == 'bool' %} default=True
|
||||
{%- elif model.pd_type == 'float' %} default=0.0
|
||||
{%- elif model.pd_type == 'date' %} default_factory=date.today
|
||||
{%- elif model.pd_type == 'datetime' and model.type in ['TIMESTAMP', 'DateTime', 'TIMESTAMP WITHOUT TIME ZONE', 'TIMESTAMP WITH TIME ZONE'] %} default_factory=timezone.now
|
||||
{%- elif model.pd_type == 'datetime' %} default_factory=datetime.now
|
||||
{%- else %} default=None
|
||||
{%- endif -%}, comment=
|
||||
{%- if model.comment != None -%}
|
||||
'{{ model.comment }}')
|
||||
{% else -%}
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
{% if default_datetime_column %}
|
||||
from datetime import datetime
|
||||
{% set pd_types = models|map(attribute='pd_type')|list %}
|
||||
{% set NEED_DATETIME = datetime_mixin or 'datetime' in pd_types %}
|
||||
{% set NEED_DATE = 'date' in pd_types %}
|
||||
{% set NEED_TIME = 'time' in pd_types %}
|
||||
{% set NEED_TIMEDELTA = 'timedelta' in pd_types %}
|
||||
{% set NEED_DECIMAL = 'Decimal' in pd_types %}
|
||||
{% set NEED_UUID = 'UUID' in pd_types or 'str | UUID' in pd_types %}
|
||||
{% if NEED_DATETIME or NEED_DATE or NEED_TIME or NEED_TIMEDELTA %}
|
||||
from datetime import {% if NEED_DATETIME %}datetime{% endif %}{% if NEED_DATE %}{% if NEED_DATETIME %}, {% endif %}date{% endif %}{% if NEED_TIME %}{% if NEED_DATETIME or NEED_DATE %}, {% endif %}time{% endif %}{% if NEED_TIMEDELTA %}{% if NEED_DATETIME or NEED_DATE or NEED_TIME %}, {% endif %}timedelta{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% if NEED_DECIMAL %}
|
||||
from decimal import Decimal
|
||||
|
||||
{% endif %}
|
||||
{% if NEED_UUID %}
|
||||
from uuid import UUID
|
||||
|
||||
{% endif %}
|
||||
from pydantic import ConfigDict, Field
|
||||
@@ -35,7 +50,7 @@ class Get{{ schema_name }}Detail({{ schema_name }}SchemaBase):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
{% if default_datetime_column %}
|
||||
{% if datetime_mixin %}
|
||||
created_time: datetime
|
||||
updated_time: datetime | None = None
|
||||
{% endif %}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
insert into sys_menu (title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values ('{{ doc_comment }}', '{{ schema_name }}', '/{{ app_name }}/{{ table_name|replace("_", "-") }}', 0, 'tabler:list', 1, '/{{ app_name }}/{{ table_name }}/views/index', null, 1, 1, 1, '', null, null, now(), null);
|
||||
|
||||
set @parent_menu_id = LAST_INSERT_ID();
|
||||
|
||||
insert into sys_menu (title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values
|
||||
('新增', 'Add{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:add', 1, 0, 1, '', null, @parent_menu_id, now(), null),
|
||||
('修改', 'Edit{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:edit', 1, 0, 1, '', null, @parent_menu_id, now(), null),
|
||||
('删除', 'Delete{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:del', 1, 0, 1, '', null, @parent_menu_id, now(), null),
|
||||
('查询', 'Get{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:get', 1, 0, 1, '', null, @parent_menu_id, now(), null);
|
||||
@@ -0,0 +1,9 @@
|
||||
insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values ({{ parent_menu_id }}, '{{ doc_comment }}', '{{ schema_name }}', '/{{ app_name }}/{{ table_name|replace("_", "-") }}', 0, 'tabler:list', 1, '/{{ app_name }}/{{ table_name }}/views/index', null, 1, 1, 1, '', null, null, now(), null);
|
||||
|
||||
insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values
|
||||
({{ button_ids[0] }}, '新增', 'Add{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:add', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[1] }}, '修改', 'Edit{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:edit', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[2] }}, '删除', 'Delete{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:del', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[3] }}, '查询', 'Get{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:get', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null);
|
||||
@@ -0,0 +1,17 @@
|
||||
do $$
|
||||
declare
|
||||
parent_menu_id bigint;
|
||||
begin
|
||||
insert into sys_menu (title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values ('{{ doc_comment }}', '{{ schema_name }}', '/{{ app_name }}/{{ table_name|replace("_", "-") }}', 0, 'tabler:list', 1, '/{{ app_name }}/{{ table_name }}/views/index', null, 1, 1, 1, '', null, null, now(), null)
|
||||
returning id into parent_menu_id;
|
||||
|
||||
insert into sys_menu (title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values
|
||||
('新增', 'Add{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:add', 1, 0, 1, '', null, parent_menu_id, now(), null),
|
||||
('修改', 'Edit{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:edit', 1, 0, 1, '', null, parent_menu_id, now(), null),
|
||||
('删除', 'Delete{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:del', 1, 0, 1, '', null, parent_menu_id, now(), null),
|
||||
('查询', 'Get{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:get', 1, 0, 1, '', null, parent_menu_id, now(), null);
|
||||
end $$;
|
||||
|
||||
select setval(pg_get_serial_sequence('sys_menu', 'id'),coalesce(max(id), 0) + 1, true) from sys_menu;
|
||||
@@ -0,0 +1,9 @@
|
||||
insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values ({{ parent_menu_id }}, '{{ doc_comment }}', '{{ schema_name }}', '/{{ app_name }}/{{ table_name|replace("_", "-") }}', 0, 'tabler:list', 1, '/{{ app_name }}/{{ table_name }}/views/index', null, 1, 1, 1, '', null, null, now(), null);
|
||||
|
||||
insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time)
|
||||
values
|
||||
({{ button_ids[0] }}, '新增', 'Add{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:add', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[1] }}, '修改', 'Edit{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:edit', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[2] }}, '删除', 'Delete{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:del', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null),
|
||||
({{ button_ids[3] }}, '查询', 'Get{{ schema_name }}', null, 0, null, 2, null, '{{ permission }}:get', 1, 0, 1, '', null, {{ parent_menu_id }}, now(), null);
|
||||
Reference in New Issue
Block a user