sqlor/aidocs/ddl_template_postgresql.md
2025-10-05 11:24:24 +08:00

7.8 KiB
Raw Permalink Blame History

以下是为提供的 Jinja2 模板代码编写的 Markdown 格式技术文档,用于描述该 PostgreSQL DDL 生成模板的功能、结构和使用方式。


PostgreSQL DDL 生成模板技术文档

概述

postgresql_ddl_tmpl 是一个基于 Jinja2 模板引擎的字符串模板,用于自动生成符合 PostgreSQL 语法的 数据定义语言 (DDL) 脚本。它可以根据表结构元数据(如字段类型、长度、是否可为空、主键、索引等)动态生成完整的 CREATE TABLE 语句,包括:

  • 表的创建与删除
  • 字段定义及其数据类型映射
  • 主键约束
  • 索引(普通或唯一)
  • 表和字段的注释

该模板适用于自动化建模工具、ETL 流程或数据库同步系统中,实现从元数据到物理表结构的自动转换。


模板源码

postgresql_ddl_tmpl = """{% macro typeStr(type,len,dec) %}
{%- if type=='str' -%}
VARCHAR({{len}})
{%- elif type=='char' -%}
CHAR({{len}})
{%- elif type=='long' or type=='int' or type=='short' -%}
NUMERIC(30,0)
{%- elif type=='float' or type=='double' or type=='ddouble' -%}
NUMERIC({{len}},{{dec}})
{%- elif type=='date' -%}
DATE
{%- elif type=='time' -%}
TIME
{%- elif type=='timestamp' -%}
TIMESTAMP
{%- else -%}
{{type}}
{%- endif %}
{%- endmacro %}
{% macro nullStr(nullable) %}
{%- if nullable=='no' -%}
NOT NULL
{%- endif -%}
{% endmacro %}
{% macro primary() %}
,PRIMARY KEY({{','.join(summary[0].primary)}})
{% endmacro %}
DROP TABLE IF EXISTS {{summary[0].name}};
CREATE TABLE {{summary[0].name}}
(
{% for field in fields %}
  {{field.name}} {{typeStr(field.type,field.length,field.dec)}} {{nullStr(field.nullable)}}{%- if not loop.last -%},{%- endif -%}
{% endfor %}
{% if summary[0].primary and len(summary[0].primary)>0 %}
{{primary()}}
{% endif %}
);
{% for v in indexes %}
CREATE {% if v.idxtype=='unique' %}UNIQUE{% endif %} INDEX {{summary[0].name}}_{{v.name}} ON {{summary[0].name}}({{",".join(v.idxfields)}});
{%- endfor -%}
COMMENT ON TABLE {{summary[0].name}} IS '{{summary[0].title}}';
{% for field in fields %}
COMMENT ON COLUMN {{summary[0].name}}.{{field.name}} is '{{field.title}}';
{% endfor %}
"""

模板变量说明

变量名 类型 描述
summary[0] 对象 包含表级别的元信息对象,必须是列表且第一个元素有效
  .name 字符串 表名(如 "users"
  .title 字符串 表的中文/描述性标题,用于 COMMENT
  .primary 列表 主键字段名称列表(如 ["id"]["user_id", "tenant_id"]
fields 列表 字段对象列表,每个对象代表一列
  .name 字符串 字段名(如 "username"
  .type 字符串 字段逻辑类型(见下文“类型映射”)
  .length 整数 字段长度(对字符串和数值类型有意义)
  .dec 整数 小数位数decimal scale
  .nullable 字符串 是否允许为空:"yes" 表示可空,"no" 表示 NOT NULL
  .title 字符串 字段的中文/描述性标题,用于 COMMENT
indexes 列表 索引定义对象列表
  .name 字符串 索引名称标识(将用于生成索引名)
  .idxtype 字符串 索引类型,若为 "unique" 则创建唯一索引
  .idxfields 列表 索引包含的字段名列表(如 ["email"]["status", "created_time"]

内置宏Macros

typeStr(type, len, dec)

根据字段的逻辑类型映射为 PostgreSQL 实际数据类型。

逻辑类型 映射结果
'str' VARCHAR(len)
'char' CHAR(len)
'long', 'int', 'short' NUMERIC(30,0) (高精度整数)
'float', 'double', 'ddouble' NUMERIC(len, dec)
'date' DATE
'time' TIME
'timestamp' TIMESTAMP
其他未知类型 原样输出 {{type}}(可用于扩展)

⚠️ 注意:浮点类型统一使用 NUMERIC 以保证精度;如需性能优化可后续调整为 REAL / DOUBLE PRECISION


nullStr(nullable)

生成 NOT NULL 约束。

  • nullable == 'no' → 输出 NOT NULL
  • 否则不输出任何内容(即允许为空)

primary()

生成主键约束子句。

  • 使用 summary[0].primary 中的字段名,通过逗号拼接
  • 示例:主键为 ["id"] → 输出 ,PRIMARY KEY(id)
  • 注意:前面有一个英文逗号,依赖前一行结尾,因此必须确保前面有换行和逗号处理

生成的 DDL 结构说明

  1. 删除旧表

    DROP TABLE IF EXISTS table_name;
    

    避免重复建表错误。

  2. 创建新表

    CREATE TABLE table_name (...);
    
    • 包含所有字段定义
    • 自动添加主键约束(如果存在)
    • 支持多字段联合主键
  3. 创建索引

    CREATE [UNIQUE] INDEX table_name_idxname ON table_name(field1, field2);
    
    • 支持普通索引和唯一索引
    • 索引命名规则:{table_name}_{index_name}
  4. 添加注释

    COMMENT ON TABLE table_name IS '用户信息表';
    COMMENT ON COLUMN table_name.username IS '用户名';
    
    • 提升数据库可读性和文档性

使用示例

假设输入上下文如下Python 字典形式):

context = {
    "summary": [{
        "name": "users",
        "title": "用户信息表",
        "primary": ["id"]
    }],
    "fields": [
        {"name": "id", "type": "long", "length": 30, "dec": 0, "nullable": "no", "title": "用户ID"},
        {"name": "username", "type": "str", "length": 50, "dec": 0, "nullable": "no", "title": "用户名"},
        {"name": "email", "type": "str", "length": 100, "dec": 0, "nullable": "yes", "title": "邮箱地址"},
        {"name": "created_time", "type": "timestamp", "length": 0, "dec": 0, "nullable": "no", "title": "创建时间"}
    ],
    "indexes": [
        {"name": "email_idx", "idxtype": "unique", "idxfields": ["email"]}
    ]
}

渲染后输出 SQL

DROP TABLE IF EXISTS users;
CREATE TABLE users
(
  id NUMERIC(30,0) NOT NULL,
  username VARCHAR(50) NOT NULL,
  email VARCHAR(100),
  created_time TIMESTAMP NOT NULL,
  PRIMARY KEY(id)
);

CREATE UNIQUE INDEX users_email_idx ON users(email);

COMMENT ON TABLE users IS '用户信息表';
COMMENT ON COLUMN users.id is '用户ID';
COMMENT ON COLUMN users.username is '用户名';
COMMENT ON COLUMN users.email is '邮箱地址';
COMMENT ON COLUMN users.created_time is '创建时间';

扩展建议

  • 支持默认值:可在字段中增加 .default 属性,并在模板中扩展。
  • 外键支持:当前未处理外键,可根据需要添加 FOREIGN KEY 子句。
  • 字符集/排序规则PostgreSQL 通常使用数据库级设置,也可显式指定。
  • 分区表支持:复杂场景下可扩展模板支持 PARTITION BY

注意事项

  1. primary() 宏前会自动加 ,,因此必须确保前面字段定义已正确结束并换行。
  2. 所有字段的 lengthdec 必须提供,即使某些类型不需要(可用占位值如 0)。
  3. summary 必须是一个非空列表,summary[0] 是实际使用的表元数据。
  4. 索引名应避免冲突,推荐命名清晰(如 idx_status)。

总结

postgresql_ddl_tmpl 是一个功能完整、结构清晰的 DDL 自动生成模板,适合集成进元数据驱动的数据平台。其优势在于:

  • 类型抽象良好,便于业务人员理解
  • 支持常见约束与注释
  • 易于维护和扩展

通过此模板,可以高效地将模型设计转化为可执行的数据库脚本,提升开发效率与一致性。


文档版本1.0
📅 最后更新2025年4月5日