如何在TypeORM中让继承类使用不同数据源实现PostgreSQL审计日志
TypeORM实现PostgreSQL审计日志:实体跨独立数据源配置
我需要基于TypeORM为PostgreSQL实现审计日志功能,设计思路是创建_Demo类继承自业务实体Demo,二者属性完全一致,但_Demo要连接到独立的审计数据库(使用单独的数据源)。当前同一数据源下的实体功能已正常运行,现在需要调整_Demo的数据源关联逻辑。
现有代码片段
数据源连接逻辑
await AuditDataSource.dataSourceConnection.connect(); if (dataSourceOptions.synchronize) { await AuditDataSource.dataSourceConnection.sync(false);
数据源配置
private static connectionOptions: DataSourceOptions = { type: "postgres", host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE_NAME, entities: [ process.env.NODE_ENV === "build" ? process.env.BUILD_MODEL_PATH : process.env.DEV_MODEL_PATH, ], synchronize: true, logging: true, };
业务实体与审计实体定义
@Entity() @Expose() export class Demo { @PrimaryGeneratedColumn("uuid") uuid: string; @Expose() @Column() demoName: string; } @AuditEntity(Demo, { seqType: "int", specificFields: ["demoEmail", "demoBoolean"] }) export class _Demo extends Demo {}
AuditEntity装饰器核心代码片段
当前装饰器绑定默认数据源,需修改为审计专用数据源:
export function AuditEntity<T extends ObjectLiteral>(entityType: { new(): T }, options?: AuditEntityOptions) { return (target: Function) => { options = options || {}; // ... 省略其他代码 metadata.tables.push({ target, name: entityOptions.name, type: 'regular', orderBy: entityOptions.orderBy || origin.orderBy, engine: entityOptions.engine || origin.engine, database: con.database, // 此处需替换为审计数据库配置 schema: entityOptions.schema || origin.schema, synchronize: entityOptions.synchronize || origin.synchronize, withoutRowid: entityOptions.withoutRowid, } as TableMetadataArgs); // ... 省略其他代码 } }
实现方案
1. 新增审计专用数据源配置
单独创建审计数据源的配置,与业务数据源完全隔离:
// 审计数据源配置 private static auditConnectionOptions: DataSourceOptions = { type: "postgres", host: process.env.AUDIT_DB_HOST, port: parseInt(process.env.AUDIT_DB_PORT), username: process.env.AUDIT_DB_USER, password: process.env.AUDIT_DB_PASSWORD, database: process.env.AUDIT_DB_DATABASE_NAME, // 审计专用数据库 entities: [ process.env.NODE_ENV === "build" ? process.env.BUILD_AUDIT_MODEL_PATH : process.env.DEV_AUDIT_MODEL_PATH, ], synchronize: true, logging: true, }; // 初始化审计数据源实例 export const AuditDataSource = new DataSource(auditConnectionOptions);
2. 修改AuditEntity装饰器,绑定审计数据源
在装饰器中直接引用审计数据源的数据库配置,替换原有默认数据源的关联:
// 导入审计数据源实例 import { AuditDataSource } from './path-to-audit-datasource'; export function AuditEntity<T extends ObjectLiteral>(entityType: { new(): T }, options?: AuditEntityOptions) { return (target: Function) => { options = options || {}; // ... 省略其他代码 // 获取审计数据库名称 const auditDatabase = AuditDataSource.options.database; metadata.tables.push({ target, name: entityOptions.name, type: 'regular', orderBy: entityOptions.orderBy || origin.orderBy, engine: entityOptions.engine || origin.engine, database: auditDatabase, // 绑定审计数据库 schema: entityOptions.schema || origin.schema, synchronize: entityOptions.synchronize || origin.synchronize, withoutRowid: entityOptions.withoutRowid, } as TableMetadataArgs); // ... 省略其他代码 } }
3. 隔离实体注册范围
调整实体路径配置,确保_Demo这类审计实体仅被审计数据源加载,业务数据源只加载Demo等业务实体,避免数据源交叉注册。
4. 初始化审计数据源
在应用启动流程中单独初始化审计数据源:
// 启动时连接审计数据源 await AuditDataSource.initialize(); if (AuditDataSource.options.synchronize) { await AuditDataSource.synchronize(false); }
内容的提问来源于stack exchange,提问作者Josef Henn
相关产品推荐
相关产品推荐

