npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

imean-cassandra-orm

v3.1.0

Published

cassandra orm

Readme

IMean Cassandra ORM

一个基于 Zod 的 Cassandra ORM,提供类型安全的 schema 定义和数据库操作。

特性

  • 🎯 类型安全: 基于 Zod 的 schema 验证和 TypeScript 类型推断,确保入库和出库的数据类型安全。
  • 🔧 自动 CQL 生成: 自动生成 Cassandra CQL 语句,无需手写。
  • 📊 完整 CRUD: 支持插入、查询、更新、删除操作。
  • 🚀 批量操作: 支持批量插入,提升性能。
  • 🎨 简洁 API: 简单易用的 API 设计,通过 Client 统一管理模型。
  • 🔄 Schema 同步: 自动创建和同步 keyspace 和表结构。
  • ⚙️ Keyspace 配置: 支持自定义复制策略和配置。
  • 🤖 自动序列化: 自动处理复杂类型(如 JSON 对象、数组)的序列化和反序列化。
  • 📊 ClickHouse 双写: 可选的 ClickHouse 双写功能,支持实时数据分析和自动表结构同步。

安装

npm install imean-cassandra-orm

快速开始

1. 定义 Schema

使用 TableSchemazod 来定义你的表结构。ORM 会根据你的定义自动推断类型和生成数据库表。

import { z } from "zod";
import { TableSchema } from "imean-cassandra-orm";

// 定义用户表 schema
const userSchema = new TableSchema({
  fields: {
    user_id: z.string(),
    email: z.string().email(),
    name: z.string(),
    age: z.number().int().positive(),
    is_active: z.boolean(),
    metadata: z.record(z.any()), // 可以是任意复杂的对象
    created_at: z.date(),
  },
  partitionKey: ["user_id"],
  tableName: "users",
  keyspace: "my_app_keyspace",
});

// 定义帖子表 schema(带聚类键)
const postSchema = new TableSchema({
  fields: {
    user_id: z.string(),
    post_id: z.string(),
    title: z.string(),
    content: z.string(),
    tags: z.array(z.string()), // 数组类型
    published_at: z.date(),
  },
  partitionKey: ["user_id"],
  clusteringKey: { post_id: "desc" }, // 按 post_id 降序
  tableName: "posts",
  keyspace: "my_app_keyspace",
});

2. 创建 Client 和模型

Client 是所有操作的入口。你需要先创建一个 Client 实例,然后用它来创建 Model 实例。

import { Client } from "imean-cassandra-orm";

// 1. 创建 Client 实例
const client = new Client({
  contactPoints: ["localhost"],
  localDataCenter: "datacenter1",
});

// 2. 连接到 Cassandra
await client.connect();

// 3. (可选) 删除旧的 keyspace 以进行全新测试
await client.dropKeyspace("my_app_keyspace");

// 4. 通过 Client 创建模型实例
const userModel = client.createModel(userSchema);
const postModel = client.createModel(postSchema);

// 5. 同步所有模型的 Schema
// 这会确保 keyspace 和所有相关的表都已创建
// 如果启用了双写,也会同步 ClickHouse 表结构
await client.syncSchema();

client.syncSchema() 会自动处理所有已创建模型的 schema 同步,你不再需要为每个模型单独调用 syncSchema()

3. 基本操作

模型实例提供了完整的 CRUD API。

// 插入数据 (自动序列化 metadata 对象)
const userData = {
  user_id: "user1",
  email: "[email protected]",
  name: "张三",
  age: 25,
  is_active: true,
  metadata: { score: 95.5, level: 3, tags: ["vip"] },
  created_at: new Date(),
};
await userModel.insert(userData);

// 查询数据 (自动反序列化 metadata)
const foundUser = await userModel.findOne({ user_id: "user1" });
console.log(foundUser?.metadata); // { score: 95.5, level: 3, tags: ["vip"] }

// 更新数据
await userModel.update(
  { user_id: "user1" },
  { name: "李四", age: 26 }
);

// 删除数据
await userModel.delete({ user_id: "user1" });

4. 批量操作

// 批量插入
const usersData = [
  {
    user_id: "user2",
    email: "[email protected]",
    name: "王五",
    age: 30,
    is_active: true,
    metadata: { score: 88.0 },
    created_at: new Date(),
  },
  {
    user_id: "user3",
    email: "[email protected]",
    name: "赵六",
    age: 28,
    is_active: false,
    metadata: { score: 79.2 },
    created_at: new Date(),
  },
];
await userModel.batchInsert(usersData);

5. 使用聚类键

当你的 schema 定义了 clusteringKey 时,你可以在查询、更新和删除操作中指定它。

// 插入带聚类键的数据
const postData = {
  user_id: "user1",
  post_id: "post1",
  title: "我的第一篇帖子",
  content: "这是内容...",
  tags: ["技术", "编程"],
  published_at: new Date(),
};
await postModel.insert(postData);

// 查询特定帖子
const post = await postModel.findOne(
  { user_id: "user1" },
  { post_id: "post1" } // 指定聚类键
);

// 更新特定帖子
await postModel.update(
  { user_id: "user1" },
  { title: "更新后的标题" },
  { post_id: "post1" } // 指定聚类键
);

// 删除特定帖子
await postModel.delete(
  { user_id: "user1" }, 
  { post_id: "post1" } // 指定聚类键
);

6. 类型安全与校验

ORM 会在数据返回时使用 Zod schema 进行校验,确保你得到的数据是类型安全的。

// 从数据库返回的数据
const userFromDb = await userModel.findOne({ user_id: "user1" });

// userFromDb 的类型是根据 userSchema 推断出来的,具有完整的类型提示
if (userFromDb) {
  console.log(userFromDb.name.toUpperCase());
}

// 如果数据库中的数据不符合 schema(例如,手动修改了数据库),
// 在查询时会抛出 ZodError,防止脏数据进入你的应用。

ClickHouse 双写功能

框架支持可选的 ClickHouse 双写功能,可以将 Cassandra 的操作同步到 ClickHouse 中用于分析查询。

配置双写功能

import { Client } from "imean-cassandra-orm";

const client = new Client({
  contactPoints: ["localhost"],
  localDataCenter: "datacenter1",
  keyspace: "my_keyspace",
  dualWrite: {
    enabled: true,
    clickhouse: {
      host: "localhost",
      port: 8123,
      username: "default",
      password: "",
      database: "analytics",
    },
    operations: {
      insert: true,
      update: true,
      delete: true,
    },
    errorHandling: "log", // 'ignore' | 'log' | 'throw'
    debug: true,
  },
});

使用双写功能

启用双写后,所有的插入、更新、删除操作都会自动同步到 ClickHouse:

// 连接数据库
await client.connect();

// 同步 schema(会自动同步到 ClickHouse)
await client.syncSchema();

// 创建模型
const UserModel = client.createModel(userSchema);

// 插入数据(会自动双写到 ClickHouse)
await UserModel.insert({
  user_id: "user1",
  email: "[email protected]",
  name: "张三",
  age: 25,
  is_active: true,
  created_at: new Date(),
});

// 批量插入(会自动双写到 ClickHouse)
await UserModel.batchInsert([...]);

// 更新数据(会自动双写到 ClickHouse)
await UserModel.update({ user_id: "user1" }, { age: 26 });

// 删除数据(会自动双写到 ClickHouse)
await UserModel.delete({ user_id: "user1" });

检查双写状态

if (client.isDualWriteEnabled()) {
  console.log("双写功能已启用");
}

更多详细信息请参考 双写功能文档

API 参考

Client

new Client(options: cassandra.ClientOptions)

创建一个新的 Client 实例。optionscassandra-driverClientOptions 相同。

client.connect(): Promise<void>

连接到 Cassandra 集群。

client.createModel(schema: TableSchema): Model

根据 TableSchema 创建一个 Model 实例。

client.syncSchema(): Promise<void>

同步所有通过 createModel 创建的模型的 schema。

client.dropKeyspace(keyspace: string): Promise<void>

删除一个 keyspace。

Model

model.insert(data: T): Promise<void>

插入一条数据。

model.batchInsert(data: T[]): Promise<void>

批量插入多条数据。

model.find(partitionKey: PK): Promise<T[]>

根据分区键查询多条数据。

model.findOne(partitionKey: PK, clusteringKey?: CK): Promise<T | null>

根据分区键和(可选的)聚类键查询单条数据。

model.update(partitionKey: PK, data: Partial<T>, clusteringKey?: CK): Promise<void>

更新一条数据。

model.delete(partitionKey: PK, clusteringKey?: CK): Promise<void>

删除一条数据。


贡献者:imean License: MIT