You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:09:53