diff --git a/create/README.md b/create/README.md index a0ca0ab..f52b5c5 100644 --- a/create/README.md +++ b/create/README.md @@ -1,205 +1,21 @@ -这是我工程目录的组织结构: - - -```tree -. -├── LICENSE +``` +TableName +├── dev.sh ├── README.md -├── create -│ ├── README.md -│ ├── create.sh -│ └── create_table.py -├── docker-compose.yaml -├── infra -│ └── postgres -│ ├── scripts -│ │ └── db-lanuch-entrypoint.sh -│ └── sql -│ ├── 01_uuid_v7_setup.sql -│ ├── 02_create_function.sql -│ └── 03_create_table.sql -└── services -``` - - - -其中 create.sh 内容如下: - -``` -#!/bin/bash -# create.sh - 启动Python容器执行create_table.py脚本 - -set -e # 遇到错误立即退出 - -echo "🚀 启动Python容器执行create_table.py..." - -# 获取脚本所在目录的绝对路径 -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" - -# 容器名称 -CONTAINER_NAME="python-create-runner" - -# 检查是否已存在同名容器,如果存在则删除 -if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "🧹 清理已存在的容器 ${CONTAINER_NAME}..." - docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 -fi - -# 运行Python容器 -echo "📦 启动Python容器..." -docker run --rm \ - --name "${CONTAINER_NAME}" \ - -v "${SCRIPT_DIR}:/app/create" \ - -v "${PROJECT_ROOT}/infra/postgres/sql:/app/infra/postgres/sql" \ - -w /app \ - python:3.13.7-alpine3.22 \ - sh -c " - echo '📋 容器内环境信息:' - python --version - echo '' - - echo '🔧 安装依赖(如果需要)...' - pip install --quiet --no-cache-dir psycopg2-binary >/dev/null 2>&1 || true - - echo '⚙️ 执行 create_table.py...' - python create/create_table.py - - echo '' - echo '✅ 执行完成!' - " - -echo "" -echo "🎉 create.sh 执行完成!" -``` - -其中 create_table.py 内容如下: - -```python -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -create.py - 动态生成PostgreSQL建表SQL语句 -""" - -import os -import re - -# 1. 定义表名称变量,方便调整 -table_name = "cn_pmi_234_aaarecords" # 可以根据需要修改表名 - -# 2. 定义SQL模板 -sql_template = f"""DO $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 - FROM information_schema.tables - WHERE table_schema = 'public' - AND table_name = '{table_name}' - ) THEN - CREATE TABLE {table_name} ( - id UUID DEFAULT gen_random_uuid() PRIMARY KEY, -- id - payload JSONB NOT NULL, -- 数据 - deleted BOOLEAN NOT NULL DEFAULT FALSE, -- 删除状态 - created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 记录创建时间 - updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP -- 记录修改时间 - ); - - -- 3 触发器:自动刷新 updated_at - CREATE TRIGGER trg_{table_name}_at - BEFORE UPDATE ON {table_name} - FOR EACH ROW - EXECUTE FUNCTION moddatetime(updated_at); - - RAISE NOTICE '{table_name} 表已创建'; - ELSE - RAISE NOTICE '{table_name} 表已存在,跳过'; - END IF; -END $$;""" - -def normalize_blank_lines(text): - """规范化空行:确保END $$;和DO $$之间只有一个空行""" - # 将多个空行替换为单个空行 - text = re.sub(r'\n{3,}', '\n\n', text) - - # 确保END $$;后面有一个空行再接DO $$ - text = re.sub(r'END \$\$;(\s*)DO \$\$', r'END $$;\n\nDO $$', text) - - # 清理开头和结尾的多余空行 - text = text.strip() + '\n' - - return text - -def update_sql_file(): - """将生成的SQL语句追加到03_create_table.sql文件中""" - - # 定义文件路径 - sql_file_path = os.path.join( - os.path.dirname(os.path.dirname(__file__)), - 'infra', - 'postgres', - 'sql', - '03_create_table.sql' - ) - - try: - # 读取现有文件内容 - with open(sql_file_path, 'r', encoding='utf-8') as f: - content = f.read() - - # 查找插入位置(在\"部署完成\"日志前) - insert_pattern = r'(DO \$\$.*?RAISE NOTICE \'🚀============ 数据库表部署开始 ============🚀\'.*?END \$\$;)(.*?)(DO \$\$.*?RAISE NOTICE \'============ 数据库表部署完成 ============\'.*?END \$\$;)' - - match = re.search(insert_pattern, content, re.DOTALL) - - if match: - # 分割内容 - before_insert = match.group(1) - existing_middle = match.group(2) - after_insert = match.group(3) - - # 规范化空行 - existing_middle = normalize_blank_lines(existing_middle) - - # 组合新内容 - new_content = f"""{before_insert}\n\n{sql_template}\n\n{existing_middle}\n{after_insert}""" - - # 规范化整个内容的空行 - new_content = normalize_blank_lines(new_content) - - # 写回文件 - with open(sql_file_path, 'w', encoding='utf-8') as f: - f.write(new_content) - - print(f"✅ 成功更新 {sql_file_path}") - print(f"📋 生成的表名: {table_name}") - print(f"📝 SQL内容已追加到文件中") - - else: - print("❌ 无法找到插入位置,请检查文件格式") - - except FileNotFoundError: - print(f"❌ 文件 {sql_file_path} 不存在") - except Exception as e: - print(f"❌ 处理文件时出错: {e}") - -if __name__ == "__main__": - print(f"🚀 开始生成表 '{table_name}' 的SQL语句...") - update_sql_file() -``` - - - -其中 03_create_table.sql 内容如下: - -```sql -DO $$ -BEGIN - RAISE NOTICE '🚀============ 数据库表部署开始 ============🚀'; -END $$; - -DO $$ -BEGIN - RAISE NOTICE '✅============ 数据库表部署完成 ============✅'; -END $$; +└── src + ├── crud + │   └── create.go + │   └── read.go + │   └── update.go + │   └── delete.go + ├── Dockerfile + ├── go.mod + ├── go.sum + ├── infra + │   ├── launch.go + │   ├── logger.go + │   └── postgres.go + ├── main.go + └── model + └── payload.go ``` \ No newline at end of file diff --git a/create/create.sh b/create/create.sh index 8587d27..1836741 100644 --- a/create/create.sh +++ b/create/create.sh @@ -1,13 +1,17 @@ #!/bin/bash -# create.sh - 启动Python容器执行create_table.py脚本 +# create.sh - 启动Python容器执行create_table.py和create_src.py脚本 set -e # 遇到错误立即退出 # 定义表名变量,可以根据需要修改 -TABLE_NAME="cn_pmi_a_records" +TABLE_NAME="cn_pmi_234_aaarecords" +echo "🚀 开始创建流程,表名: ${TABLE_NAME}" +echo "==========================================" + +# ========== 第一部分:创建数据库表 ========== +echo "📋 第一步:创建数据库表结构..." echo "🚀 启动Python容器执行create_table.py..." -echo "📋 目标表名: ${TABLE_NAME}" # 获取脚本所在目录的绝对路径 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -22,8 +26,8 @@ if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 fi -# 运行Python容器 -echo "📦 启动Python容器..." +# 运行Python容器执行create_table.py +echo "📦 启动Python容器执行create_table.py..." docker run --rm \ --name "${CONTAINER_NAME}" \ -v "${SCRIPT_DIR}:/app/create" \ @@ -43,8 +47,36 @@ docker run --rm \ python create/create_table.py echo '' - echo '✅ 执行完成!' + echo '✅ create_table.py 执行完成!' + " + +# ========== 第二部分:创建服务结构 ========== +echo "" +echo "📋 第二步:创建服务文件夹结构..." +echo "🚀 执行create_src.py..." + +# 运行Python容器执行create_src.py +docker run --rm \ + --name "${CONTAINER_NAME}-src" \ + -v "${SCRIPT_DIR}:/app/create" \ + -v "${PROJECT_ROOT}/services:/app/services" \ + -e TABLE_NAME="${TABLE_NAME}" \ + -w /app \ + python:3.13.7-alpine3.22 \ + sh -c " + echo '📋 容器内环境信息:' + python --version + echo '' + + echo '⚙️ 执行 create_src.py...' + python create/create_src.py + + echo '' + echo '✅ create_src.py 执行完成!' " echo "" -echo "🎉 create.sh 执行完成!" \ No newline at end of file +echo "==========================================" +echo "🎉 所有任务执行完成!" +echo "📋 表名: ${TABLE_NAME}" +echo "📁 服务目录: ${PROJECT_ROOT}/services/${TABLE_NAME}" \ No newline at end of file diff --git a/create/create_src.py b/create/create_src.py new file mode 100644 index 0000000..b531b53 --- /dev/null +++ b/create/create_src.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +create_src.py - 在services目录下创建服务文件夹和文件结构 +""" + +import os +import sys + +def create_service_structure(table_name): + """创建服务文件夹结构""" + + # 获取项目根目录 + project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + services_dir = os.path.join(project_root, 'services') + + # 创建服务目录 + service_dir = os.path.join(services_dir, table_name) + + print(f"🚀 开始创建服务结构: {table_name}") + print(f"📁 目标目录: {service_dir}") + + try: + # 创建主目录 + os.makedirs(service_dir, exist_ok=True) + print(f"✅ 创建主目录: {service_dir}") + + # 创建子目录 + subdirs = ['src', 'src/crud', 'src/infra', 'src/model'] + for subdir in subdirs: + dir_path = os.path.join(service_dir, subdir) + os.makedirs(dir_path, exist_ok=True) + print(f"✅ 创建子目录: {dir_path}") + + # 定义要创建的文件列表 + files_to_create = [ + 'dev.sh', + 'README.md', + 'src/Dockerfile', + 'src/go.mod', + 'src/go.sum', + 'src/main.go', + 'src/crud/create.go', + 'src/crud/read.go', + 'src/crud/update.go', + 'src/crud/delete.go', + 'src/infra/launch.go', + 'src/infra/logger.go', + 'src/infra/postgres.go', + 'src/model/payload.go' + ] + + # 创建所有文件 + for file_path in files_to_create: + full_path = os.path.join(service_dir, file_path) + os.makedirs(os.path.dirname(full_path), exist_ok=True) # 确保目录存在 + + # 创建空文件 + with open(full_path, 'w', encoding='utf-8') as f: + f.write('') # 创建空文件 + + print(f"✅ 创建文件: {full_path}") + + print(f"🎉 服务结构创建完成: {table_name}") + return True + + except Exception as e: + print(f"❌ 创建服务结构时出错: {e}") + return False + +if __name__ == "__main__": + # 从环境变量获取表名 + table_name = os.environ.get('TABLE_NAME') + + if not table_name: + print("❌ 错误: 未设置 TABLE_NAME 环境变量") + sys.exit(1) + + print(f"📋 接收到的表名: {table_name}") + success = create_service_structure(table_name) + + if success: + sys.exit(0) + else: + sys.exit(1) \ No newline at end of file