bknd-delete-entity
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDelete Entity
删除实体
Safely remove an entity (table) from Bknd, handling dependencies and avoiding data loss.
安全地从Bknd中删除实体(数据表),处理依赖关系并避免数据丢失。
Prerequisites
前提条件
- Existing Bknd app with entities (see )
bknd-create-entity - For code mode: Access to
bknd.config.ts - Critical: Backup database before deletion
- 已创建包含实体的Bknd应用(可参考)
bknd-create-entity - 代码模式下:拥有的访问权限
bknd.config.ts - 关键操作: 删除前请备份数据库
Warning: Destructive Operation
警告:破坏性操作
Deleting an entity:
- Permanently removes the table and ALL its data
- Removes all relationships involving this entity
- May break application code referencing this entity
- Cannot be undone without database restore
删除实体将:
- 永久移除数据表及其所有数据
- 删除涉及该实体的所有关联关系
- 可能导致引用该实体的应用代码失效
- 若无数据库备份则无法撤销操作
When to Use UI vs Code
UI模式与代码模式的适用场景
Use UI Mode When
适用UI模式的场景
- Quick prototype cleanup
- Development/testing environments
- Exploring what dependencies exist
- 快速清理原型
- 开发/测试环境
- 探索实体间的依赖关系
Use Code Mode When
适用代码模式的场景
- Production changes
- Version control needed
- Team collaboration
- Reproducible deployments
- 生产环境变更
- 需要版本控制
- 团队协作
- 可重复部署的变更
Pre-Deletion Checklist
删除前检查清单
Before deleting an entity, verify:
删除实体前,请确认以下内容:
1. Check for Relationships
1. 检查关联关系
Entities may be referenced by other entities via:
- Foreign keys (many-to-one)
- Junction tables (many-to-many)
- Self-references
实体可能通过以下方式被其他实体引用:
- 外键(多对一关系)
- 关联表(多对多关系)
- 自引用
2. Check for Data
2. 检查数据量
typescript
const api = app.getApi();
const count = await api.data.count("entity_to_delete");
console.log(`Records to delete: ${count.data.count}`);typescript
const api = app.getApi();
const count = await api.data.count("entity_to_delete");
console.log(`Records to delete: ${count.data.count}`);3. Check for Code References
3. 检查代码引用
Search codebase for:
- Entity name in queries:
"entity_name" - Type references:
DB["entity_name"] - API calls:
api.data.*("entity_name")
在代码库中搜索:
- 查询语句中的实体名称:
"entity_name" - 类型引用:
DB["entity_name"] - API调用:
api.data.*("entity_name")
4. Backup Data (If Needed)
4. 备份数据(如需)
typescript
// Export data before deletion
const api = app.getApi();
const allRecords = await api.data.readMany("entity_to_delete", {
limit: 100000,
});
// Save to file
import { writeFileSync } from "fs";
writeFileSync(
"backup-entity_to_delete.json",
JSON.stringify(allRecords.data, null, 2)
);typescript
// 删除前导出数据
const api = app.getApi();
const allRecords = await api.data.readMany("entity_to_delete", {
limit: 100000,
});
// 保存到文件
import { writeFileSync } from "fs";
writeFileSync(
"backup-entity_to_delete.json",
JSON.stringify(allRecords.data, null, 2)
);Code Approach
代码操作步骤
Step 1: Identify Dependencies
步骤1:识别依赖关系
Check your schema for relationships:
typescript
// Look for relationships involving this entity
const schema = em(
{
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
comments: entity("comments", { body: text() }),
},
({ relation }, { users, posts, comments }) => {
// posts depends on users (foreign key)
relation(posts).manyToOne(users);
// comments depends on posts (foreign key)
relation(comments).manyToOne(posts);
}
);Dependency order matters: Delete children before parents.
检查schema中的关联关系:
typescript
// 查找涉及该实体的关联关系
const schema = em(
{
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
comments: entity("comments", { body: text() }),
},
({ relation }, { users, posts, comments }) => {
// posts依赖于users(外键)
relation(posts).manyToOne(users);
// comments依赖于posts(外键)
relation(comments).manyToOne(posts);
}
);依赖顺序至关重要: 先删除子实体,再删除父实体。
Step 2: Remove Relationships First
步骤2:先移除关联关系
If entity is a target of relationships, update schema to remove them:
typescript
// BEFORE: posts references users
const schema = em(
{
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
},
({ relation }, { users, posts }) => {
relation(posts).manyToOne(users);
}
);
// AFTER: Remove relationship before deleting users
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
});如果该实体是其他实体关联的目标,先更新schema移除关联关系:
typescript
// 之前:posts引用users
const schema = em(
{
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
},
({ relation }, { users, posts }) => {
relation(posts).manyToOne(users);
}
);
// 之后:删除users前先移除关联关系
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
});Step 3: Remove Entity from Schema
步骤3:从Schema中移除实体
Simply remove the entity definition from your :
bknd.config.tstypescript
// BEFORE
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
deprecated_entity: entity("deprecated_entity", { data: text() }),
});
// AFTER - entity removed
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
});直接从中删除实体定义:
bknd.config.tstypescript
// 之前
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
deprecated_entity: entity("deprecated_entity", { data: text() }),
});
// 之后 - 已移除实体
const schema = em({
users: entity("users", { email: text().required() }),
posts: entity("posts", { title: text().required() }),
});Step 4: Preview Changes
步骤4:预览变更
bash
undefinedbash
undefinedSee what will be dropped (dry run)
查看将被删除的内容(试运行)
npx bknd sync
Output shows:Tables to drop: deprecated_entity
Columns affected: (none on other tables)
undefinednpx bknd sync
输出示例:Tables to drop: deprecated_entity
Columns affected: (none on other tables)
undefinedStep 5: Apply Deletion
步骤5:执行删除
bash
undefinedbash
undefinedApply with drop flag (destructive)
使用--drop标志应用变更(破坏性操作)
npx bknd sync --drop
Or with force (enables all destructive operations):
```bash
npx bknd sync --forcenpx bknd sync --drop
或使用force标志(启用所有破坏性操作):
```bash
npx bknd sync --forceStep 6: Clean Up Code
步骤6:清理代码
Remove all references:
- Delete type definitions
- Remove API calls
- Update imports
移除所有引用:
- 删除类型定义
- 移除API调用
- 更新导入语句
UI Approach
UI操作步骤
Step 1: Open Admin Panel
步骤1:打开管理面板
Navigate to (or your configured URL).
http://localhost:1337访问(或您配置的URL)。
http://localhost:1337Step 2: Go to Data Section
步骤2:进入数据板块
Click Data in the sidebar.
点击侧边栏的Data选项。
Step 3: Select Entity
步骤3:选择实体
Click on the entity you want to delete.
点击您要删除的实体。
Step 4: Check Dependencies
步骤4:检查依赖关系
Look for:
- Relations tab/section showing connected entities
- Warning messages about dependencies
查看:
- 显示关联实体的Relations标签/板块
- 关于依赖关系的警告信息
Step 5: Export Data (Optional)
步骤5:导出数据(可选)
If you need the data:
- Go to entity's data view
- Export or manually copy records
- Save backup externally
如果需要保留数据:
- 进入实体的数据视图
- 导出或手动复制记录
- 外部保存备份
Step 6: Delete Entity
步骤6:删除实体
- Open entity settings (gear icon or settings tab)
- Look for Delete Entity or Remove button
- Confirm deletion
- Entity and all data removed
- 打开实体设置(齿轮图标或设置标签)
- 找到Delete Entity或Remove按钮
- 确认删除操作
- 实体及其所有数据将被移除
Step 7: Sync Database
步骤7:同步数据库
After deletion, ensure database is synced:
- Click Sync Database if prompted
- Or run from CLI
npx bknd sync --drop
删除后,确保数据库已同步:
- 如有提示,点击Sync Database
- 或从CLI执行
npx bknd sync --drop
Handling Dependencies
依赖关系处理
Scenario: Entity Has Child Records
场景:实体包含子记录
Problem: Deleting when has foreign key.
userspostsusers_idSolution 1: Delete Children First
typescript
// 1. Delete all posts referencing users
const api = app.getApi();
await api.data.deleteMany("posts", {});
// 2. Then delete users
// (via schema removal + sync)Solution 2: Remove Relationship First
typescript
// 1. Remove relationship from schema
// 2. Sync to remove foreign key
// 3. Remove entity from schema
// 4. Sync again with --drop问题: 当表包含外键时,删除实体。
postsusers_idusers解决方案1:先删除子实体
typescript
// 1. 删除所有引用users的posts记录
const api = app.getApi();
await api.data.deleteMany("posts", {});
// 2. 再删除users实体
// (通过移除schema定义 + 同步操作)解决方案2:先移除关联关系
typescript
// 1. 从schema中移除关联关系
// 2. 同步以移除外键
// 3. 从schema中移除实体
// 4. 再次执行sync --dropScenario: Entity is Junction Table Target
场景:实体是关联表的目标
Problem: is used in junction table.
tagsposts_tagsSolution:
typescript
// 1. Remove many-to-many relationship
const schema = em(
{
posts: entity("posts", { title: text() }),
tags: entity("tags", { name: text() }),
}
// Remove: ({ relation }, { posts, tags }) => { relation(posts).manyToMany(tags); }
);
// 2. Sync to drop junction table
// npx bknd sync --drop
// 3. Remove tags entity
const schema = em({
posts: entity("posts", { title: text() }),
});
// 4. Sync again to drop tags table
// npx bknd sync --drop问题: 实体被用于关联表中。
tagsposts_tags解决方案:
typescript
// 1. 移除多对多关联关系
const schema = em(
{
posts: entity("posts", { title: text() }),
tags: entity("tags", { name: text() }),
}
// 移除:({ relation }, { posts, tags }) => { relation(posts).manyToMany(tags); }
);
// 2. 同步以删除关联表
// npx bknd sync --drop
// 3. 移除tags实体
const schema = em({
posts: entity("posts", { title: text() }),
});
// 4. 再次同步以删除tags表
// npx bknd sync --dropScenario: Self-Referencing Entity
场景:自引用实体
Problem: references itself (parent/children).
categoriesSolution:
typescript
// 1. Remove self-reference relation
const schema = em({
categories: entity("categories", { name: text() }),
// Remove self-referencing relation definition
});
// 2. Sync to remove foreign key
// npx bknd sync --drop
// 3. Remove entity
// (then sync again)问题: 实体自引用(父/子分类)。
categories解决方案:
typescript
// 1. 移除自引用关联关系
const schema = em({
categories: entity("categories", { name: text() }),
// 移除自引用关联关系定义
});
// 2. 同步以移除外键
// npx bknd sync --drop
// 3. 移除实体
// (然后再次同步)Deleting Multiple Entities
删除多个实体
Order matters. Delete in dependency order (children first):
typescript
// Dependency tree:
// users <- posts <- comments
// <- likes
// Delete order:
// 1. comments (depends on posts)
// 2. likes (depends on posts)
// 3. posts (depends on users)
// 4. users (no dependencies)顺序至关重要。按照依赖顺序删除(先子后父):
typescript
// 依赖树:
// users <- posts <- comments
// <- likes
// 删除顺序:
// 1. comments(依赖于posts)
// 2. likes(依赖于posts)
// 3. posts(依赖于users)
// 4. users(无依赖)Batch Deletion Script
批量删除脚本
typescript
// scripts/cleanup-entities.ts
import { App } from "bknd";
async function cleanup() {
const app = new App({
connection: { url: process.env.DB_URL! },
});
await app.build();
const api = app.getApi();
// Delete in order
const entitiesToDelete = ["comments", "likes", "posts"];
for (const entity of entitiesToDelete) {
const count = await api.data.count(entity);
console.log(`Deleting ${count.data.count} records from ${entity}...`);
await api.data.deleteMany(entity, {});
console.log(`Deleted all records from ${entity}`);
}
console.log("Data cleanup complete. Now remove from schema and sync.");
}
cleanup().catch(console.error);typescript
// scripts/cleanup-entities.ts
import { App } from "bknd";
async function cleanup() {
const app = new App({
connection: { url: process.env.DB_URL! },
});
await app.build();
const api = app.getApi();
// 按顺序删除
const entitiesToDelete = ["comments", "likes", "posts"];
for (const entity of entitiesToDelete) {
const count = await api.data.count(entity);
console.log(`Deleting ${count.data.count} records from ${entity}...`);
await api.data.deleteMany(entity, {});
console.log(`Deleted all records from ${entity}`);
}
console.log("数据清理完成。现在请从schema中移除实体并同步。");
}
cleanup().catch(console.error);Common Pitfalls
常见陷阱
Foreign Key Constraint Error
外键约束错误
Error:
Cannot drop table: foreign key constraintCause: Another entity references this one.
Fix: Remove relationship first, sync, then remove entity.
错误信息:
Cannot drop table: foreign key constraint原因: 其他实体引用了该实体。
解决方法: 先移除关联关系,同步后再删除实体。
Junction Table Not Dropped
关联表未被删除
Problem: After removing many-to-many relation, junction table remains.
Fix: Run to include destructive operations.
npx bknd sync --drop问题: 移除多对多关联关系后,关联表仍存在。
解决方法: 执行以包含破坏性操作。
npx bknd sync --dropEntity Still Appears in UI
实体仍在UI中显示
Problem: Deleted from code but still shows in admin panel.
Fix:
- Ensure you ran
npx bknd sync --drop - Restart the Bknd server
- Clear browser cache
问题: 已通过代码删除实体,但管理面板中仍可见。
解决方法:
- 确保已执行
npx bknd sync --drop - 重启Bknd服务器
- 清除浏览器缓存
Application Crashes After Deletion
删除后应用崩溃
Problem: Code still references deleted entity.
Fix:
- Search codebase:
grep -r "entity_name" src/ - Remove all API calls, types, imports
- Fix TypeScript errors
问题: 代码仍引用已删除的实体。
解决方法:
- 在代码库中搜索:
grep -r "entity_name" src/ - 移除所有API调用、类型定义和导入语句
- 修复TypeScript错误
Accidentally Deleted Wrong Entity
误删错误实体
Problem: Deleted production data.
Fix:
- If you have backup: Restore from backup
- If no backup: Data is permanently lost
- Prevention: Always backup before deletion
问题: 删除了生产环境中的数据。
解决方法:
- 若有备份:从备份恢复
- 若无备份:数据将永久丢失
- 预防措施:删除前务必备份
Verification
验证操作
After Deletion
删除后检查
bash
undefinedbash
undefined1. Check schema export (entity should be absent)
1. 检查schema导出(实体应不存在)
npx bknd schema --pretty | grep entity_name
npx bknd schema --pretty | grep entity_name
2. Verify sync status
2. 验证同步状态
npx bknd sync
npx bknd sync
Should show no pending changes
应显示无待处理变更
undefinedundefinedVia Code
通过代码验证
typescript
const api = app.getApi();
// This should fail/return error for deleted entity
try {
await api.data.readMany("deleted_entity", { limit: 1 });
console.log("ERROR: Entity still exists!");
} catch (e) {
console.log("Confirmed: Entity deleted successfully");
}typescript
const api = app.getApi();
// 已删除的实体应返回错误
try {
await api.data.readMany("deleted_entity", { limit: 1 });
console.log("错误:实体仍存在!");
} catch (e) {
console.log("确认:实体已成功删除");
}Via REST API
通过REST API验证
bash
undefinedbash
undefinedShould return 404 or error
应返回404或错误
DOs and DON'Ts
注意事项
DO:
- Backup data before deletion
- Check for dependencies first
- Delete children before parents
- Preview with before
npx bknd sync--drop - Remove code references after deletion
- Test in development before production
DON'T:
- Delete entities with active foreign keys
- Use without previewing changes
--drop - Delete in production without backup
- Assume UI deletion handles all cleanup
- Forget to remove TypeScript types/code references
请遵循:
- 删除前备份数据
- 先检查依赖关系
- 先删除子实体再删除父实体
- 执行前先用
--drop预览变更npx bknd sync - 删除后移除代码中的引用
- 先在开发环境测试再部署到生产环境
请勿:
- 删除存在活跃外键引用的实体
- 未预览变更就使用
--drop - 无备份时在生产环境删除实体
- 认为UI删除能处理所有清理工作
- 忘记移除TypeScript类型和代码引用
Related Skills
相关技能
- bknd-create-entity - Create new entities
- bknd-modify-schema - Modify existing schema
- bknd-define-relationship - Understand relationship dependencies
- bknd-crud-delete - Delete individual records (not tables)
- bknd-seed-data - Restore data from backup
- bknd-create-entity - 创建新实体
- bknd-modify-schema - 修改现有schema
- bknd-define-relationship - 理解关联关系依赖
- bknd-crud-delete - 删除单个记录(非数据表)
- bknd-seed-data - 从备份恢复数据