Skip to main content

electric-orm

Use Electric with Drizzle ORM or Prisma for the write path. Covers getting pg_current_xact_id() from ORM transactions using Drizzle tx.execute(sql) and Prisma $queryRaw, running migrations that preserve REPLICA IDENTITY FULL, and schema management patterns compatible with Electric shapes. Load when using Drizzle or Prisma alongside Electric for writes.

来源信息

仓库
electric-sql/electric
最近来源活动
2026年3月6日 21:27
检测到的 SKILL.md 语言
英语
星标
10,384
分支
392

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
electric-orm
description
Use Electric with Drizzle ORM or Prisma for the write path. Covers getting pg_current_xact_id() from ORM transactions using Drizzle tx.execute(sql) and Prisma $queryRaw, running migrations that preserve REPLICA IDENTITY FULL, and schema management patterns compatible with Electric shapes. Load when using Drizzle or Prisma alongside Electric for writes.
type
composition
library
electric
library_version
1.5.10
requires
["electric-shapes","electric-schema-shapes"]
sources
["electric-sql/electric:AGENTS.md","electric-sql/electric:website/docs/guides/troubleshooting.md"]
This skill builds on electric-shapes and electric-schema-shapes. Read those first. # Electric — ORM Integration ## Setup ### Drizzle ORM ```ts import { drizzle } from 'drizzle-orm/node-postgres' import { sql } from 'drizzle-orm' import { todos } from './schema' const db = drizzle(pool) // Write with txid for Electric reconciliation async function createTodo(text: string, userId: string) { return await db.transaction(async (tx) => { const [row] = await tx .insert(todos) .values({ id: crypto.randomUUID(), text, userId, }) .returning() const [{ txid }] = await tx.execute<{ txid: string }>( sql`SELECT pg_current_xact_id()::xid::text AS txid` ) return { id: row.id, txid: parseInt(txid) } }) } ``` ### Prisma ```ts import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() async function createTodo(text: string, userId: string) { return await prisma.$transaction(async (tx) => { const todo = await tx.todo.create({ data: { id: crypto.randomUUID(), text, userId }, }) const [{ txid }] = await tx.$queryRaw<[{ txid: string }]>` SELECT pg_current_xact_id()::xid::text AS txid ` return { id: todo.id, txid: parseInt(txid) } }) } ``` ## Core Patterns ### Drizzle migration with REPLICA IDENTITY ```ts // In migration file import { sql } from 'drizzle-orm' export async function up(db) { await db.execute(sql` CREATE TABLE todos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), text TEXT NOT NULL, completed BOOLEAN DEFAULT false ) `) await db.execute(sql`ALTER TABLE todos REPLICA IDENTITY FULL`) } ``` ### Prisma migration with REPLICA IDENTITY ```sql -- prisma/migrations/001_init/migration.sql CREATE TABLE "todos" ( "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(), "text" TEXT NOT NULL, "completed" BOOLEAN DEFAULT false ); ALTER TABLE "todos" REPLICA IDENTITY FULL; ``` ### Collection onInsert with ORM ```ts import { createCollection } from '@tanstack/react-db' import { electricCollectionOptions } from '@tanstack/electric-db-collection' export const todoCollection = createCollection( electricCollectionOptions({ id: 'todos', schema: todoSchema, getKey: (row) => row.id, shapeOptions: { url: '/api/todos' }, onInsert: async ({ transaction }) => { const newTodo = transaction.mutations[0].modified const { txid } = await createTodo(newTodo.text, newTodo.userId) return { txid } }, }) ) ``` ## Common Mistakes ### HIGH Not returning txid from ORM write operations Wrong: ```ts // Drizzle — no txid returned const [todo] = await db.insert(todos).values({ text: 'New' }).returning() return { id: todo.id } ``` Correct: ```ts // Drizzle — txid in same transaction const result = await db.transaction(async (tx) => { const [row] = await tx.insert(todos).values({ text: 'New' }).returning() const [{ txid }] = await tx.execute<{ txid: string }>( sql`SELECT pg_current_xact_id()::xid::text AS txid` ) return { id: row.id, txid: parseInt(txid) } }) ``` ORMs do not return `pg_current_xact_id()` by default. Add a raw SQL query for txid within the same transaction. Without it, optimistic state may drop before the synced version arrives, causing UI flicker. Source: `AGENTS.md:116-119` ### MEDIUM Running migrations that drop replica identity Wrong: ```ts // ORM migration recreates table without REPLICA IDENTITY await db.execute(sql`DROP TABLE todos`) await db.execute(sql`CREATE TABLE todos (...)`) // Missing: ALTER TABLE todos REPLICA IDENTITY FULL ``` Correct: ```ts await db.execute(sql`DROP TABLE todos`) await db.execute(sql`CREATE TABLE todos (...)`) await db.execute(sql`ALTER TABLE todos REPLICA IDENTITY FULL`) ``` Some migration tools reset table properties. Always ensure `REPLICA IDENTITY FULL` is set after table recreation. Without it, Electric cannot stream updates and deletes correctly. Source: `website/docs/guides/troubleshooting.md:373` See also: electric-new-feature/SKILL.md — Full write-path journey including txid handshake. See also: electric-schema-shapes/SKILL.md — Schema design affects both shapes and ORM queries. ## Version Targets @electric-sql/client v1.5.10.
在 GitHub 查看