Files
BIPMaterialManager/docs/plans/2026-04-05-postgresql-integration-design.md
2026-04-05 11:56:22 +08:00

5.2 KiB
Raw Permalink Blame History

PostgreSQL 集成设计文档

日期: 2026-04-05 状态: 已批准 分支: dev-logging

目标

将 PostgreSQL 作为第三种可选数据库类型集成到 ERPAuto 中,与现有 MySQL、SQL Server 并列。通过引入 SqlDialect 抽象层,统一管理三种数据库的 SQL 方言差异,同时重构现有 DAO 层消除散落的 isSqlServer 判断。

背景

  • PostgreSQL 数据库已通过 SSMA 从 SQL Server 迁移完成表结构、schema 组织、列名完全一致
  • 连接信息:postgresql://admin:***@192.168.31.83:5432/postgres,数据库 CompanyDB
  • 共 15 个 schema、151 张表,dbo schema 包含 ERPAuto 直接使用的表

方案:抽象数据库方言层

1. SqlDialect 接口

新建 src/main/types/sql-dialect.types.ts

export interface SqlDialect {
  readonly dbType: DatabaseType

  // 表名引用
  quoteTableName(schema: string, table: string): string

  // 参数占位符
  param(index: number): string
  params(count: number): string

  // SQL 函数
  currentTimestamp(): string

  // UPSERT
  upsert(p: {
    table: string
    keyColumns: string[]
    valueColumns: string[]
    placeholderCount: number
    startParamIndex: number
  }): string

  // 分页
  paginate(p: { sql: string; limit: number; offset?: number; paramIndex: number }): {
    sql: string
    paramIndex: number
  }

  // 批量限制
  maxBatchRows(columnsPerRow: number): number
}

2. 三种方言实现

新建 src/main/services/database/dialects/ 目录:

文件 数据库 param(n) quoteTableName currentTimestamp upsert paginate
mysql-dialect.ts MySQL ? dbo_Table NOW() ON DUPLICATE KEY LIMIT x OFFSET y
sqlserver-dialect.ts SQL Server @p{n} [dbo].[Table] GETDATE() MERGE OFFSET/FETCH
postgresql-dialect.ts PostgreSQL ${n+1} "dbo"."Table" CURRENT_TIMESTAMP ON CONFLICT LIMIT x OFFSET y

方言工厂 dialects/index.ts

export function createDialect(type: DatabaseType): SqlDialect

3. DAO 层重构

每个 DAO 新增 dialect 成员,替代原有的 getTableName()buildPlaceholders() 和所有 isSqlServer 分支:

删除:

  • getTableName() 私有方法
  • buildPlaceholders() 私有方法
  • 所有 isSqlServer 局部变量和条件分支
  • *_CONFIG 中的 TABLE_NAME_SQLSERVER / TABLE_NAME_MYSQL → 合并为 TABLE_SCHEMA + TABLE_NAME

新增:

  • private dialect: SqlDialect | null = null
  • private getDialect(): SqlDialect

涉及 DAO

  • DiscreteMaterialPlanDAO — 占位符、表名、批量大小
  • MaterialsToBeDeletedDAO — 占位符、表名、MERGE/ON DUPLICATE KEY → upsert()
  • MaterialsTypeToBeDeletedDAO — 同上
  • ExtractorOperationHistoryDAO — 占位符、表名、GETDATE()/NOW() → currentTimestamp()、分页 → paginate()

4. PostgreSQL 服务层

新建 src/main/services/database/postgresql.ts

  • 使用 pg 驱动,Pool 连接池
  • 实现 IDatabaseService 接口
  • query() 直接传递参数数组给 pg
  • transaction() 使用 client.query('BEGIN/COMMIT/ROLLBACK')

5. 工厂、配置、TypeORM

database/index.ts create() 新增 'postgresql' 分支,新增 createPostgreSqlConfig()

database.types.ts DatabaseType 扩展为 'mysql' | 'sqlserver' | 'postgresql',新增 PostgreSqlConfig

data-source.ts TypeORM type 映射新增 'postgres'

config.template.yaml 新增 postgresql 配置段

package.json 新增 pg 依赖

改动范围

文件 动作
类型 types/database.types.ts 修改
方言 database/dialects/index.ts 新建
方言 database/dialects/mysql-dialect.ts 新建
方言 database/dialects/sqlserver-dialect.ts 新建
方言 database/dialects/postgresql-dialect.ts 新建
服务 database/postgresql.ts 新建
工厂 database/index.ts 修改
TypeORM database/data-source.ts 修改
DAO database/discrete-material-plan-dao.ts 重构
DAO database/materials-to-be-deleted-dao.ts 重构
DAO database/materials-type-to-be-deleted-dao.ts 重构
DAO database/extractor-operation-history-dao.ts 重构
配置 config.template.yaml 修改
依赖 package.json 修改

4 个新文件 + 10 个修改文件

不在范围内

  • IPC 处理器新增(前端暂不需要直接切换 PostgreSQL
  • Entity/Repository 的 TypeScript 类型适配TypeORM 内部处理方言差异)
  • 数据迁移工具
  • 前端 UI 变更