Files
fastapi-best-architecture/backend/plugin/code_generator/templates/python/model.jinja
T
Wu Clan 1a6aba6105 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
2026-01-20 18:27:42 +08:00

96 lines
4.5 KiB
Django/Jinja

{% set DECIMAL_TYPES = ['DECIMAL', 'NUMERIC', 'MONEY', 'NUMMULTIRANGE', 'NUMRANGE'] %}
{% set MYSQL_TYPES = ['BIT', 'ENUM', 'LONGBLOB', 'LONGTEXT', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'SET',
'TINYBLOB', 'TINYINT', 'TINYTEXT', 'YEAR'] %}
{% set POSTGRESQL_TYPES = ['ARRAY', 'BIT', 'BYTEA', 'CIDR', 'CITEXT', 'DATEMULTIRANGE', 'DATERANGE', 'DOMAIN', 'ENUM',
'HSTORE', 'INET', 'INT4MULTIRANGE', 'INT4RANGE', 'INT8MULTIRANGE', 'INT8RANGE', 'INTERVAL', 'JSONB', 'JSONPATH',
'MACADDR', 'MACADDR8', 'MONEY', 'NUMMULTIRANGE', 'NUMRANGE', 'OID', 'REGCLASS', 'REGCONFIG', 'TSMULTIRANGE', 'TSQUERY',
'TSRANGE', 'TSTZMULTIRANGE', 'TSTZRANGE', 'TSVECTOR'] %}
{% 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 %}
import sqlalchemy as sa
{% if NEED_MYSQL_DIALECT %}
from sqlalchemy.dialects import mysql
{% endif %}
{% if NEED_PGSQL_DIALECT %}
from sqlalchemy.dialects import postgresql
{% endif %}
from sqlalchemy.orm import Mapped, mapped_column
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 datetime_mixin %}Base{% else %}DataClassBase{% endif %}):
"""{{ table_comment }}"""
__tablename__ = '{{ table_name }}'
id: Mapped[id_key] = mapped_column(init=False)
{% for model in models %}
{{ model.name }}:
{%- if model.is_nullable %} Mapped[{{ model.pd_type }} | None]
{%- else %} Mapped[{{ model.pd_type }}]
{%- endif %} = mapped_column(
{%- 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|sqlalchemy_type }}()
{%- elif database_type == 'postgresql' and model.type in POSTGRESQL_TYPES -%}
{%- if model.type == 'ARRAY' -%}
postgresql.ARRAY(sa.String)
{%- else -%}
postgresql.{{ model.type|sqlalchemy_type }}()
{%- endif -%}
{%- 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 -%}
None)
{%- endif -%}
{% endfor %}