Loading...
Loading...
Use when removing an entity from Bknd. Covers safely deleting entities, handling relationships and dependencies, data backup, the sync workflow with --drop flag, and cleaning up orphaned data.
npx skill4agent add cameronapak/bknd-skills bknd-delete-entitybknd-create-entitybknd.config.tsconst api = app.getApi();
const count = await api.data.count("entity_to_delete");
console.log(`Records to delete: ${count.data.count}`);"entity_name"DB["entity_name"]api.data.*("entity_name")// 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)
);// 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);
}
);// 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() }),
});bknd.config.ts// 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() }),
});# See what will be dropped (dry run)
npx bknd syncTables to drop: deprecated_entity
Columns affected: (none on other tables)# Apply with drop flag (destructive)
npx bknd sync --dropnpx bknd sync --forcehttp://localhost:1337npx bknd sync --dropuserspostsusers_id// 1. Delete all posts referencing users
const api = app.getApi();
await api.data.deleteMany("posts", {});
// 2. Then delete users
// (via schema removal + sync)// 1. Remove relationship from schema
// 2. Sync to remove foreign key
// 3. Remove entity from schema
// 4. Sync again with --droptagsposts_tags// 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 --dropcategories// 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)// 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)// 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);Cannot drop table: foreign key constraintnpx bknd sync --dropnpx bknd sync --dropgrep -r "entity_name" src/# 1. Check schema export (entity should be absent)
npx bknd schema --pretty | grep entity_name
# 2. Verify sync status
npx bknd sync
# Should show no pending changesconst 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");
}# Should return 404 or error
curl http://localhost:1337/api/data/deleted_entitynpx bknd sync--drop--drop