Using TypeScript types from your OLTP ORM to model OLAP tables (Drizzle, Prisma, TypeORM, MooseStack)

We’ve been working on a ClickHouse + TypeScript stack and wanted to avoid bending a OLTP ORM to work with an OLAP database.

Turns out you can reuse your ORM’s inferred types and extend them for OLAP without much friction.

// Define your OLTP data model

export const customerAddresses = pgTable("customer_addresses", {
  id: serial("id").primaryKey(),
  first_name: varchar("first_name", { length: 100 }).notNull(),
  last_name: varchar("last_name", { length: 100 }).notNull(),
  ...

// Extract TS native type
export type CustomerAddress = typeof customerAddresses.$inferSelect;

// Define your OLAP data model, adding CH specific types and optimizations
export type OlapCustomerAddress = Omit<
  CustomerAddress,
  "id" | "country" | "state" | "work_address" | "phone_2"
> &
  CdcFields & {
    id: UInt64;// stricter type
    country: string & LowCardinality; // stricter type
    state: string & LowCardinality;   // stricter type
    work_address: string & ClickHouseDefault<"''">; // default instead of nullable
    phone_2?: string;                 // nullable (OLAP practice if 95%+ NULL)
  };

// Create OLAP table
export const olapCustomerAddresses = new OlapTable<OlapCustomerAddress>(
  "customer_addresses",
  {
    engine: ClickHouseEngines.ReplacingMergeTree,
    ver: "lsn",                   // Version field for deduplication
    isDeleted: "_is_deleted",     // Soft delete marker
    orderByFields: ["id"],        // Sorting key (also used for dedup)
  }
);

We then generate the ClickHouse DDL (ReplacingMergeTree, ORDER BY, etc.) from that type — so type safety and schema-as-code carry across both systems.

Write-up and code: https://www.fiveonefour.com/blog/derive-an-olap-data-model-from-your-oltp-orm

——

Would love community feedback on what ORMs you'd want to see supported, and on our implementation.

Posted Oct 22, 2025, 5:19 PM UTC

20
Loading comments…