bknd-crud-update
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCRUD Update
CRUD 更新操作
Update existing records in your Bknd database using the SDK or REST API.
使用SDK或REST API更新Bknd数据库中的现有记录。
Prerequisites
前提条件
- Bknd project running (local or deployed)
- Entity exists with records to update
- SDK configured or API endpoint known
- Record ID or filter criteria known
- Bknd项目已运行(本地或已部署)
- 存在包含待更新记录的实体
- 已配置SDK或已知API端点
- 已知记录ID或筛选条件
When to Use UI Mode
何时使用UI模式
- Quick one-off edits
- Manual data corrections
- Visual verification during development
UI steps: Admin Panel > Data > Select Entity > Click record > Edit fields > Save
- 快速的一次性编辑
- 手动数据修正
- 开发过程中的可视化验证
UI操作步骤: 管理面板 > 数据 > 选择实体 > 点击记录 > 编辑字段 > 保存
When to Use Code Mode
何时使用代码模式
- Application logic for user edits
- Form submissions
- Bulk updates
- Automated data maintenance
- 用户编辑的应用逻辑实现
- 表单提交处理
- 批量更新
- 自动化数据维护
Code Approach
代码实现方式
Step 1: Set Up SDK Client
步骤1:初始化SDK客户端
typescript
import { Api } from "bknd";
const api = new Api({
host: "http://localhost:7654",
});
// If auth required:
api.updateToken("your-jwt-token");typescript
import { Api } from "bknd";
const api = new Api({
host: "http://localhost:7654",
});
// If auth required:
api.updateToken("your-jwt-token");Step 2: Update Single Record
步骤2:更新单条记录
Use :
updateOne(entity, id, data)typescript
const { ok, data, error } = await api.data.updateOne("posts", 1, {
title: "Updated Title",
status: "published",
});
if (ok) {
console.log("Updated post:", data.id);
} else {
console.error("Failed:", error.message);
}使用:
updateOne(entity, id, data)typescript
const { ok, data, error } = await api.data.updateOne("posts", 1, {
title: "Updated Title",
status: "published",
});
if (ok) {
console.log("Updated post:", data.id);
} else {
console.error("Failed:", error.message);
}Step 3: Handle Response
步骤3:处理响应
The response object:
typescript
type UpdateResponse = {
ok: boolean; // Success/failure
data?: { // Updated record (if ok)
id: number;
// ...all fields with new values
};
error?: { // Error info (if !ok)
message: string;
code: string;
};
};响应对象结构:
typescript
type UpdateResponse = {
ok: boolean; // Success/failure
data?: { // Updated record (if ok)
id: number;
// ...all fields with new values
};
error?: { // Error info (if !ok)
message: string;
code: string;
};
};Step 4: Partial Updates
步骤4:部分更新
Only changed fields are required - other fields remain unchanged:
typescript
// Only update title, keep everything else
await api.data.updateOne("posts", 1, {
title: "New Title Only",
});
// Update multiple fields
await api.data.updateOne("users", 5, {
name: "New Name",
bio: "Updated bio",
updated_at: new Date().toISOString(),
});仅需提供修改的字段 - 其他字段保持不变:
typescript
// Only update title, keep everything else
await api.data.updateOne("posts", 1, {
title: "New Title Only",
});
// Update multiple fields
await api.data.updateOne("users", 5, {
name: "New Name",
bio: "Updated bio",
updated_at: new Date().toISOString(),
});Step 5: Update Relations
步骤5:更新关联关系
Change Linked Record (Many-to-One)
修改关联记录(多对一)
typescript
// Change post author to user ID 2
await api.data.updateOne("posts", 1, {
author: { $set: 2 },
});typescript
// Change post author to user ID 2
await api.data.updateOne("posts", 1, {
author: { $set: 2 },
});Unlink Record (Set to NULL)
取消关联记录(设置为NULL)
typescript
// Remove author link
await api.data.updateOne("posts", 1, {
author: { $unset: true },
});typescript
// Remove author link
await api.data.updateOne("posts", 1, {
author: { $unset: true },
});Many-to-Many: Add Relations
多对多:添加关联
typescript
// Add tags 4 and 5 to existing tags
await api.data.updateOne("posts", 1, {
tags: { $add: [4, 5] },
});typescript
// Add tags 4 and 5 to existing tags
await api.data.updateOne("posts", 1, {
tags: { $add: [4, 5] },
});Many-to-Many: Remove Relations
多对多:移除关联
typescript
// Remove tag 2 from post
await api.data.updateOne("posts", 1, {
tags: { $remove: [2] },
});typescript
// Remove tag 2 from post
await api.data.updateOne("posts", 1, {
tags: { $remove: [2] },
});Many-to-Many: Replace All Relations
多对多:替换所有关联
typescript
// Replace all tags with new set
await api.data.updateOne("posts", 1, {
tags: { $set: [1, 3, 5] },
});typescript
// Replace all tags with new set
await api.data.updateOne("posts", 1, {
tags: { $set: [1, 3, 5] },
});Combined Field and Relation Update
字段与关联关系组合更新
typescript
await api.data.updateOne("posts", 1, {
title: "Updated Post",
status: "published",
author: { $set: newAuthorId },
tags: { $add: [newTagId] },
});typescript
await api.data.updateOne("posts", 1, {
title: "Updated Post",
status: "published",
author: { $set: newAuthorId },
tags: { $add: [newTagId] },
});Step 6: Update Multiple Records (Bulk)
步骤6:更新多条记录(批量)
Use :
updateMany(entity, where, data)typescript
// Archive all draft posts
const { ok, data } = await api.data.updateMany(
"posts",
{ status: { $eq: "draft" } }, // where clause (required)
{ status: "archived" }, // update values
);
// data contains affected records
console.log("Archived", data.length, "posts");Important: clause is required to prevent accidental update-all.
wheretypescript
// Update posts by author
await api.data.updateMany(
"posts",
{ author_id: { $eq: userId } },
{ author_id: newUserId },
);
// Update old records
await api.data.updateMany(
"sessions",
{ last_active: { $lt: "2024-01-01" } },
{ expired: true },
);使用:
updateMany(entity, where, data)typescript
// Archive all draft posts
const { ok, data } = await api.data.updateMany(
"posts",
{ status: { $eq: "draft" } }, // where clause (required)
{ status: "archived" }, // update values
);
// data contains affected records
console.log("Archived", data.length, "posts");重要提示: 条件是必填项,以防止意外更新所有记录。
wheretypescript
// Update posts by author
await api.data.updateMany(
"posts",
{ author_id: { $eq: userId } },
{ author_id: newUserId },
);
// Update old records
await api.data.updateMany(
"sessions",
{ last_active: { $lt: "2024-01-01" } },
{ expired: true },
);REST API Approach
REST API 实现方式
Update One
更新单条记录
bash
curl -X PATCH http://localhost:7654/api/data/posts/1 \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title", "status": "published"}'bash
curl -X PATCH http://localhost:7654/api/data/posts/1 \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title", "status": "published"}'Update with Auth
带认证的更新
bash
curl -X PATCH http://localhost:7654/api/data/posts/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"title": "Protected Update"}'bash
curl -X PATCH http://localhost:7654/api/data/posts/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"title": "Protected Update"}'Update Relations
更新关联关系
bash
undefinedbash
undefinedChange author
Change author
curl -X PATCH http://localhost:7654/api/data/posts/1
-H "Content-Type: application/json"
-d '{"author": {"$set": 2}}'
-H "Content-Type: application/json"
-d '{"author": {"$set": 2}}'
curl -X PATCH http://localhost:7654/api/data/posts/1
-H "Content-Type: application/json"
-d '{"author": {"$set": 2}}'
-H "Content-Type: application/json"
-d '{"author": {"$set": 2}}'
Add tags
Add tags
curl -X PATCH http://localhost:7654/api/data/posts/1
-H "Content-Type: application/json"
-d '{"tags": {"$add": [4, 5]}}'
-H "Content-Type: application/json"
-d '{"tags": {"$add": [4, 5]}}'
undefinedcurl -X PATCH http://localhost:7654/api/data/posts/1
-H "Content-Type: application/json"
-d '{"tags": {"$add": [4, 5]}}'
-H "Content-Type: application/json"
-d '{"tags": {"$add": [4, 5]}}'
undefinedUpdate Many
批量更新
bash
curl -X PATCH "http://localhost:7654/api/data/posts?where=%7B%22status%22%3A%22draft%22%7D" \
-H "Content-Type: application/json" \
-d '{"status": "archived"}'bash
curl -X PATCH "http://localhost:7654/api/data/posts?where=%7B%22status%22%3A%22draft%22%7D" \
-H "Content-Type: application/json" \
-d '{"status": "archived"}'React Integration
React 集成
Edit Form
编辑表单
tsx
import { useApp } from "bknd/react";
import { useState, useEffect } from "react";
function EditPostForm({ postId }: { postId: number }) {
const { api } = useApp();
const [title, setTitle] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Load existing data
useEffect(() => {
api.data.readOne("posts", postId).then(({ data }) => {
if (data) setTitle(data.title);
});
}, [postId]);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setLoading(true);
setError(null);
const { ok, error: apiError } = await api.data.updateOne("posts", postId, {
title,
});
setLoading(false);
if (!ok) {
setError(apiError.message);
}
}
return (
<form onSubmit={handleSubmit}>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Post title"
/>
<button type="submit" disabled={loading}>
{loading ? "Saving..." : "Save"}
</button>
{error && <p className="error">{error}</p>}
</form>
);
}tsx
import { useApp } from "bknd/react";
import { useState, useEffect } from "react";
function EditPostForm({ postId }: { postId: number }) {
const { api } = useApp();
const [title, setTitle] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Load existing data
useEffect(() => {
api.data.readOne("posts", postId).then(({ data }) => {
if (data) setTitle(data.title);
});
}, [postId]);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setLoading(true);
setError(null);
const { ok, error: apiError } = await api.data.updateOne("posts", postId, {
title,
});
setLoading(false);
if (!ok) {
setError(apiError.message);
}
}
return (
<form onSubmit={handleSubmit}>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Post title"
/>
<button type="submit" disabled={loading}>
{loading ? "Saving..." : "Save"}
</button>
{error && <p className="error">{error}</p>}
</form>
);
}With SWR Revalidation
结合SWR重新验证
tsx
import useSWR, { mutate } from "swr";
function useUpdatePost() {
const { api } = useApp();
async function updatePost(id: number, updates: object) {
const { ok, data, error } = await api.data.updateOne("posts", id, updates);
if (ok) {
// Revalidate the post and list
mutate(`posts/${id}`);
mutate("posts");
}
return { ok, data, error };
}
return { updatePost };
}tsx
import useSWR, { mutate } from "swr";
function useUpdatePost() {
const { api } = useApp();
async function updatePost(id: number, updates: object) {
const { ok, data, error } = await api.data.updateOne("posts", id, updates);
if (ok) {
// Revalidate the post and list
mutate(`posts/${id}`);
mutate("posts");
}
return { ok, data, error };
}
return { updatePost };
}Optimistic Update
乐观更新
tsx
function useOptimisticUpdate() {
const { api } = useApp();
const [posts, setPosts] = useState<Post[]>([]);
async function updatePost(id: number, updates: Partial<Post>) {
// Optimistic: update immediately
const originalPosts = [...posts];
setPosts((prev) =>
prev.map((p) => (p.id === id ? { ...p, ...updates } : p))
);
// Actual update
const { ok } = await api.data.updateOne("posts", id, updates);
if (!ok) {
// Rollback on failure
setPosts(originalPosts);
}
return { ok };
}
return { posts, updatePost };
}tsx
function useOptimisticUpdate() {
const { api } = useApp();
const [posts, setPosts] = useState<Post[]>([]);
async function updatePost(id: number, updates: Partial<Post>) {
// Optimistic: update immediately
const originalPosts = [...posts];
setPosts((prev) =>
prev.map((p) => (p.id === id ? { ...p, ...updates } : p))
);
// Actual update
const { ok } = await api.data.updateOne("posts", id, updates);
if (!ok) {
// Rollback on failure
setPosts(originalPosts);
}
return { ok };
}
return { posts, updatePost };
}Full Example
完整示例
typescript
import { Api } from "bknd";
const api = new Api({ host: "http://localhost:7654" });
// Authenticate
await api.auth.login({ email: "user@example.com", password: "password" });
// Simple field update
const { ok, data } = await api.data.updateOne("posts", 1, {
title: "Updated Title",
updated_at: new Date().toISOString(),
});
// Update with relation changes
await api.data.updateOne("posts", 1, {
status: "published",
published_at: new Date().toISOString(),
category: { $set: 3 }, // Change category
tags: { $add: [7, 8] }, // Add new tags
});
// Bulk update: mark old drafts as archived
await api.data.updateMany(
"posts",
{
status: { $eq: "draft" },
created_at: { $lt: "2024-01-01" },
},
{ status: "archived" }
);
// Toggle boolean field
const post = await api.data.readOne("posts", 1);
if (post.ok) {
await api.data.updateOne("posts", 1, {
featured: !post.data.featured,
});
}typescript
import { Api } from "bknd";
const api = new Api({ host: "http://localhost:7654" });
// Authenticate
await api.auth.login({ email: "user@example.com", password: "password" });
// Simple field update
const { ok, data } = await api.data.updateOne("posts", 1, {
title: "Updated Title",
updated_at: new Date().toISOString(),
});
// Update with relation changes
await api.data.updateOne("posts", 1, {
status: "published",
published_at: new Date().toISOString(),
category: { $set: 3 }, // Change category
tags: { $add: [7, 8] }, // Add new tags
});
// Bulk update: mark old drafts as archived
await api.data.updateMany(
"posts",
{
status: { $eq: "draft" },
created_at: { $lt: "2024-01-01" },
},
{ status: "archived" }
);
// Toggle boolean field
const post = await api.data.readOne("posts", 1);
if (post.ok) {
await api.data.updateOne("posts", 1, {
featured: !post.data.featured,
});
}Common Patterns
常见模式
Upsert (Update or Insert)
Upsert(更新或插入)
typescript
async function upsert(
api: Api,
entity: string,
where: object,
data: object
) {
const { data: existing } = await api.data.readOneBy(entity, { where });
if (existing) {
return api.data.updateOne(entity, existing.id, data);
}
return api.data.createOne(entity, data);
}
// Usage
await upsert(
api,
"settings",
{ key: { $eq: "theme" } },
{ key: "theme", value: "dark" }
);typescript
async function upsert(
api: Api,
entity: string,
where: object,
data: object
) {
const { data: existing } = await api.data.readOneBy(entity, { where });
if (existing) {
return api.data.updateOne(entity, existing.id, data);
}
return api.data.createOne(entity, data);
}
// Usage
await upsert(
api,
"settings",
{ key: { $eq: "theme" } },
{ key: "theme", value: "dark" }
);Conditional Update
条件更新
typescript
async function updateIf(
api: Api,
entity: string,
id: number,
condition: (record: any) => boolean,
updates: object
) {
const { data: current } = await api.data.readOne(entity, id);
if (!current || !condition(current)) {
return { ok: false, error: { message: "Condition not met" } };
}
return api.data.updateOne(entity, id, updates);
}
// Only update if not published
await updateIf(
api,
"posts",
1,
(post) => post.status !== "published",
{ title: "New Title" }
);typescript
async function updateIf(
api: Api,
entity: string,
id: number,
condition: (record: any) => boolean,
updates: object
) {
const { data: current } = await api.data.readOne(entity, id);
if (!current || !condition(current)) {
return { ok: false, error: { message: "Condition not met" } };
}
return api.data.updateOne(entity, id, updates);
}
// Only update if not published
await updateIf(
api,
"posts",
1,
(post) => post.status !== "published",
{ title: "New Title" }
);Increment/Decrement Field
字段递增/递减
typescript
async function increment(
api: Api,
entity: string,
id: number,
field: string,
amount: number = 1
) {
const { data: current } = await api.data.readOne(entity, id);
if (!current) return { ok: false };
return api.data.updateOne(entity, id, {
[field]: current[field] + amount,
});
}
// Increment view count
await increment(api, "posts", 1, "view_count");
// Decrement stock
await increment(api, "products", 5, "stock", -1);typescript
async function increment(
api: Api,
entity: string,
id: number,
field: string,
amount: number = 1
) {
const { data: current } = await api.data.readOne(entity, id);
if (!current) return { ok: false };
return api.data.updateOne(entity, id, {
[field]: current[field] + amount,
});
}
// Increment view count
await increment(api, "posts", 1, "view_count");
// Decrement stock
await increment(api, "products", 5, "stock", -1);Soft Delete
软删除
typescript
async function softDelete(api: Api, entity: string, id: number) {
return api.data.updateOne(entity, id, {
deleted_at: new Date().toISOString(),
});
}
async function restore(api: Api, entity: string, id: number) {
return api.data.updateOne(entity, id, {
deleted_at: null,
});
}typescript
async function softDelete(api: Api, entity: string, id: number) {
return api.data.updateOne(entity, id, {
deleted_at: new Date().toISOString(),
});
}
async function restore(api: Api, entity: string, id: number) {
return api.data.updateOne(entity, id, {
deleted_at: null,
});
}Batch Update with Progress
带进度的批量更新
typescript
async function batchUpdate(
api: Api,
entity: string,
updates: Array<{ id: number; data: object }>,
onProgress?: (done: number, total: number) => void
) {
const results = [];
for (let i = 0; i < updates.length; i++) {
const { id, data } = updates[i];
const result = await api.data.updateOne(entity, id, data);
results.push(result);
onProgress?.(i + 1, updates.length);
}
return results;
}
// Usage
await batchUpdate(
api,
"products",
[
{ id: 1, data: { price: 19.99 } },
{ id: 2, data: { price: 29.99 } },
{ id: 3, data: { price: 39.99 } },
],
(done, total) => console.log(`${done}/${total}`)
);typescript
async function batchUpdate(
api: Api,
entity: string,
updates: Array<{ id: number; data: object }>,
onProgress?: (done: number, total: number) => void
) {
const results = [];
for (let i = 0; i < updates.length; i++) {
const { id, data } = updates[i];
const result = await api.data.updateOne(entity, id, data);
results.push(result);
onProgress?.(i + 1, updates.length);
}
return results;
}
// Usage
await batchUpdate(
api,
"products",
[
{ id: 1, data: { price: 19.99 } },
{ id: 2, data: { price: 29.99 } },
{ id: 3, data: { price: 39.99 } },
],
(done, total) => console.log(`${done}/${total}`)
);Common Pitfalls
常见陷阱
Record Not Found
记录未找到
Problem: Update returns no data or error.
Fix: Verify record exists first:
typescript
const { data: existing } = await api.data.readOne("posts", id);
if (!existing) {
throw new Error("Post not found");
}
await api.data.updateOne("posts", id, updates);问题: 更新操作返回无数据或错误。
解决方法: 先验证记录是否存在:
typescript
const { data: existing } = await api.data.readOne("posts", id);
if (!existing) {
throw new Error("Post not found");
}
await api.data.updateOne("posts", id, updates);Invalid Relation ID
无效的关联ID
Problem:
FOREIGN KEY constraint failedFix: Verify related record exists:
typescript
// Wrong - author ID doesn't exist
await api.data.updateOne("posts", 1, { author: { $set: 999 } });
// Correct - verify first
const { data: author } = await api.data.readOne("users", newAuthorId);
if (author) {
await api.data.updateOne("posts", 1, { author: { $set: newAuthorId } });
}问题: 出现错误
FOREIGN KEY constraint failed解决方法: 验证关联记录是否存在:
typescript
// Wrong - author ID doesn't exist
await api.data.updateOne("posts", 1, { author: { $set: 999 } });
// Correct - verify first
const { data: author } = await api.data.readOne("users", newAuthorId);
if (author) {
await api.data.updateOne("posts", 1, { author: { $set: newAuthorId } });
}Unique Constraint Violation
唯一约束冲突
Problem: when updating to existing value.
UNIQUE constraint failedFix: Check uniqueness before update:
typescript
// Check if email already taken by another user
const { data: existing } = await api.data.readOneBy("users", {
where: {
email: { $eq: newEmail },
id: { $ne: currentUserId }, // Exclude current user
},
});
if (existing) {
throw new Error("Email already in use");
}
await api.data.updateOne("users", currentUserId, { email: newEmail });问题: 更新为已存在的值时出现错误。
UNIQUE constraint failed解决方法: 更新前检查唯一性:
typescript
// Check if email already taken by another user
const { data: existing } = await api.data.readOneBy("users", {
where: {
email: { $eq: newEmail },
id: { $ne: currentUserId }, // Exclude current user
},
});
if (existing) {
throw new Error("Email already in use");
}
await api.data.updateOne("users", currentUserId, { email: newEmail });Not Checking Response
未检查响应结果
Problem: Assuming success without verification.
Fix: Always check :
oktypescript
// Wrong
const { data } = await api.data.updateOne("posts", 1, updates);
console.log(data.title); // data might be undefined!
// Correct
const { ok, data, error } = await api.data.updateOne("posts", 1, updates);
if (!ok) {
throw new Error(error.message);
}
console.log(data.title);问题: 假设更新操作一定成功而不进行验证。
解决方法: 始终检查状态:
oktypescript
// Wrong
const { data } = await api.data.updateOne("posts", 1, updates);
console.log(data.title); // data might be undefined!
// Correct
const { ok, data, error } = await api.data.updateOne("posts", 1, updates);
if (!ok) {
throw new Error(error.message);
}
console.log(data.title);Updating Without Auth
未认证就进行更新
Problem: error.
UnauthorizedFix: Authenticate first:
typescript
await api.auth.login({ email, password });
// or
api.updateToken(savedToken);
await api.data.updateOne("posts", 1, updates);问题: 出现错误。
Unauthorized解决方法: 先进行认证:
typescript
await api.auth.login({ email, password });
// or
api.updateToken(savedToken);
await api.data.updateOne("posts", 1, updates);Using Wrong Relation Operator
使用错误的关联操作符
Problem: Replacing when intending to add.
Fix: Use correct operator:
typescript
// $set replaces ALL relations
await api.data.updateOne("posts", 1, { tags: { $set: [5] } });
// Post now has ONLY tag 5
// $add keeps existing and adds new
await api.data.updateOne("posts", 1, { tags: { $add: [5] } });
// Post keeps existing tags AND adds tag 5问题: 本想添加关联却使用了替换操作。
解决方法: 使用正确的操作符:
typescript
// $set replaces ALL relations
await api.data.updateOne("posts", 1, { tags: { $set: [5] } });
// Post now has ONLY tag 5
// $add keeps existing and adds new
await api.data.updateOne("posts", 1, { tags: { $add: [5] } });
// Post keeps existing tags AND adds tag 5Forgetting updateMany Where Clause
批量更新时忘记添加where条件
Problem: Trying to update all without where.
Fix: Always provide where clause:
typescript
// updateMany requires where clause
await api.data.updateMany(
"posts",
{ status: { $eq: "draft" } }, // Required
{ status: "archived" }
);
// To update ALL records, use explicit condition
await api.data.updateMany(
"posts",
{ id: { $gt: 0 } }, // Match all
{ reviewed: true }
);问题: 尝试在没有where条件的情况下更新所有记录。
解决方法: 始终提供where条件:
typescript
// updateMany requires where clause
await api.data.updateMany(
"posts",
{ status: { $eq: "draft" } }, // Required
{ status: "archived" }
);
// To update ALL records, use explicit condition
await api.data.updateMany(
"posts",
{ id: { $gt: 0 } }, // Match all
{ reviewed: true }
);Verification
验证
After updating, verify changes:
typescript
const { ok } = await api.data.updateOne("posts", 1, { title: "New Title" });
if (ok) {
const { data } = await api.data.readOne("posts", 1);
console.log("Updated title:", data.title);
}Or via admin panel: Admin Panel > Data > Select Entity > Find record > Verify fields.
更新完成后,验证修改是否生效:
typescript
const { ok } = await api.data.updateOne("posts", 1, { title: "New Title" });
if (ok) {
const { data } = await api.data.readOne("posts", 1);
console.log("Updated title:", data.title);
}或通过管理面板验证:管理面板 > 数据 > 选择实体 > 找到记录 > 检查字段值。
DOs and DON'Ts
注意事项
DO:
- Check before using response data
ok - Verify record exists before updating
- Use /
$addfor incremental relation changes$remove - Handle unique constraint errors
- Authenticate before updating protected records
- Revalidate caches after updates
DON'T:
- Assume updateOne always succeeds
- Use for relations when meaning
$set$add - Update without where clause in updateMany
- Ignore validation errors
- Forget to refresh UI after updates
- Use non-existent IDs in relation operators
建议:
- 使用响应数据前先检查状态
ok - 更新前验证记录是否存在
- 关联关系的增量修改使用/
$add$remove - 处理唯一约束相关错误
- 更新受保护记录前先进行认证
- 更新后重新验证缓存数据
禁止:
- 假设updateOne操作一定成功
- 本想使用却用了
$add处理关联关系$set - 批量更新时不添加where条件
- 忽略验证错误
- 更新后忘记刷新UI
- 在关联操作符中使用不存在的ID
Related Skills
相关技能
- bknd-crud-create - Create records before updating
- bknd-crud-read - Fetch records to get current values
- bknd-crud-delete - Remove records instead of updating
- bknd-define-relationship - Set up relations for linking
- bknd-bulk-operations - Large-scale update patterns
- bknd-crud-create - 更新前先创建记录
- bknd-crud-read - 获取记录当前值
- bknd-crud-delete - 删除记录而非更新
- bknd-define-relationship - 配置关联关系
- bknd-bulk-operations - 大规模更新模式