Complete guide to updating bundle schemas and adding relationships in SyndrDB.
The UPDATE BUNDLE statement modifies existing bundles by renaming them, changing their schema, or adding relationships.
Standard Syntax:
UPDATE BUNDLE "<BUNDLE_NAME>" <OPERATION>;
Available Operations:
UPDATE BUNDLE supports three main operations that can be used independently:
| Operation | Purpose | Example |
|---|---|---|
SET NAME |
Rename bundle | UPDATE BUNDLE "users" SET NAME = "customers"; |
SET (...) |
Modify fields | UPDATE BUNDLE "users" SET ({ADD "age" = "int", TRUE, FALSE, 0}); |
ADD RELATIONSHIP |
Link bundles | UPDATE BUNDLE "users" ADD RELATIONSHIP (...); |
💡 Note: Each operation is independent and can be executed separately.
Rename an existing bundle.
Syntax:
UPDATE BUNDLE "<OLD_NAME>" SET NAME = "<NEW_NAME>";
Example:
UPDATE BUNDLE "users" SET NAME = "customers";
Response:
Bundle renamed from 'users' to 'customers'.
Use Cases:
Important Notes:
Add, modify, or remove fields in a bundle's schema.
Syntax:
UPDATE BUNDLE "<BUNDLE_NAME>"
SET (
{<MODIFICATION_TYPE> "<FIELD_NAME>" = "<NEW_FIELD_NAME>", "<TYPE>", <REQUIRED>, <UNIQUE>, <DEFAULT>},
...
);
Modification Types:
ADD - Add a new fieldMODIFY - Change an existing fieldREMOVE - Remove an existing fieldAdd new fields to an existing bundle.
Syntax:
UPDATE BUNDLE "<BUNDLE_NAME>"
SET (
{ADD "<FIELD_NAME>" = "<FIELD_NAME>", "<TYPE>", <REQUIRED>, <UNIQUE>, <DEFAULT>}
);
📝 Note: For ADD operations, the field name appears twice (current name = new name) for consistency.
Single Field Example:
UPDATE BUNDLE "users"
SET (
{ADD "age" = "age", "int", FALSE, FALSE, 0}
);
Multiple Fields Example:
UPDATE BUNDLE "users"
SET (
{ADD "age" = "age", "int", FALSE, FALSE, 0},
{ADD "city" = "city", "string", FALSE, FALSE, ""},
{ADD "verified" = "verified", "bool", FALSE, FALSE, FALSE}
);
Response:
Bundle 'users' updated successfully. Added 3 field(s).
Use Cases:
Change properties of existing fields.
Syntax:
UPDATE BUNDLE "<BUNDLE_NAME>"
SET (
{MODIFY "<OLD_FIELD_NAME>" = "<NEW_FIELD_NAME>", "<TYPE>", <REQUIRED>, <UNIQUE>, <DEFAULT>}
);
Rename Field Example:
UPDATE BUNDLE "users"
SET (
{MODIFY "name" = "full_name", "string", TRUE, FALSE, ""}
);
Change Field Properties:
UPDATE BUNDLE "users"
SET (
{MODIFY "email" = "email", "string", TRUE, TRUE, ""}
);
Makes email field both required and unique.
Change Data Type:
UPDATE BUNDLE "products"
SET (
{MODIFY "price" = "price", "float", TRUE, FALSE, 0.0}
);
Converts price from int to float.
Multiple Modifications:
UPDATE BUNDLE "users"
SET (
{MODIFY "name" = "full_name", "string", TRUE, FALSE, ""},
{MODIFY "active" = "is_active", "bool", TRUE, FALSE, TRUE}
);
Response:
Bundle 'users' updated successfully. Modified 2 field(s).
Use Cases:
Remove fields from a bundle schema.
Syntax:
UPDATE BUNDLE "<BUNDLE_NAME>"
SET (
{REMOVE "<FIELD_NAME>" = "", "", FALSE, FALSE, NULL}
);
📝 Note: For REMOVE operations, only the field name is significant. Other values are placeholders.
Single Field Example:
UPDATE BUNDLE "users"
SET (
{REMOVE "middle_name" = "", "", FALSE, FALSE, NULL}
);
Multiple Fields Example:
UPDATE BUNDLE "users"
SET (
{REMOVE "temp_field" = "", "", FALSE, FALSE, NULL},
{REMOVE "old_status" = "", "", FALSE, FALSE, NULL}
);
Response:
Bundle 'users' updated successfully. Removed 2 field(s).
Use Cases:
⚠️ Warning: Removing fields will delete the data in those fields from all documents!
Create relationships between bundles to enable JOIN queries and foreign key constraints.
Syntax:
UPDATE BUNDLE "<SOURCE_BUNDLE>"
ADD RELATIONSHIP (
"<RELATIONSHIP_TYPE>",
"<SOURCE_BUNDLE>",
"<SOURCE_FIELD>",
"<DESTINATION_BUNDLE>",
"<DESTINATION_FIELD>"
);
Parameters:
| Parameter | Description | Example |
|---|---|---|
| Source Bundle | Bundle being updated | "users" |
| Relationship Type | Type of relationship | "1toMany" |
| Source Bundle (param) | Source bundle name (repeated) | "users" |
| Source Field | Field in source bundle | "DocumentID" or "id" |
| Destination Bundle | Related bundle name | "orders" |
| Destination Field | Field in destination bundle | "user_id" |
SyndrDB supports three relationship types:
One record in the source bundle relates to many records in the destination bundle.
Syntax:
"1toMany"
Example:
UPDATE BUNDLE "users"
ADD RELATIONSHIP (
"1toMany",
"users",
"DocumentID",
"orders",
"user_id"
);
Use Cases:
Diagram:
Users (1) ←→ (Many) Orders
├─ user_1 → order_1, order_2, order_3
├─ user_2 → order_4, order_5
└─ user_3 → order_6
Zero or more records in the source bundle relate to many records in the destination bundle.
Syntax:
"0toMany"
Example:
UPDATE BUNDLE "categories"
ADD RELATIONSHIP (
"0toMany",
"categories",
"DocumentID",
"products",
"category_id"
);
Use Cases:
Diagram:
Categories (0..N) ←→ (Many) Products
├─ category_1 → product_1, product_2
├─ category_2 → (no products)
└─ category_3 → product_3, product_4, product_5
Many records in the source bundle relate to many records in the destination bundle.
Syntax:
"ManyToMany"
Example:
UPDATE BUNDLE "students"
ADD RELATIONSHIP (
"ManyToMany",
"students",
"DocumentID",
"courses",
"CourseID"
);
Use Cases:
Diagram:
Students (Many) ←→ (Many) Courses
├─ student_1 → course_A, course_B
├─ student_2 → course_B, course_C
└─ student_3 → course_A, course_C
course_A ← student_1, student_3
course_B ← student_1, student_2
course_C ← student_2, student_3
Relationship fields connect documents between bundles.
Standard Mapping:
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"DocumentID", -- Primary key in authors
"books",
"author_id" -- Foreign key in books
);
How it works:
DocumentID in authors matches author_id in booksExample Documents:
Authors bundle:
{"DocumentID": "author-123", "name": "Jane Austen"}
Books bundle:
{"DocumentID": "book-456", "title": "Pride and Prejudice", "author_id": "author-123"}
If source or destination fields are empty strings, SyndrDB uses intelligent defaults.
Empty Field Defaults:
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"", -- Defaults to "DocumentID"
"books",
"" -- Defaults to "authorsID" (source bundle name + "ID")
);
Equivalent to:
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"DocumentID",
"books",
"authorsID"
);
Default Field Rules:
"DocumentID""<SourceBundleName>ID"UPDATE BUNDLE "users"
SET (
{ADD "phone" = "phone", "string", FALSE, FALSE, NULL},
{ADD "address" = "address", "string", FALSE, FALSE, ""},
{ADD "city" = "city", "string", FALSE, FALSE, ""},
{ADD "country" = "country", "string", FALSE, FALSE, "USA"},
{ADD "postal_code" = "postal_code", "string", FALSE, FALSE, ""},
{ADD "verified_email" = "verified_email", "bool", FALSE, FALSE, FALSE}
);
Use Case: Extending user profile with contact and location information.
-- Step 1: Rename fields
UPDATE BUNDLE "users"
SET (
{MODIFY "name" = "full_name", "string", TRUE, FALSE, ""},
{MODIFY "active" = "is_active", "bool", TRUE, FALSE, TRUE},
{MODIFY "created" = "created_at", "datetime", TRUE, FALSE, "2025-01-01T00:00:00Z"}
);
-- Step 2: Rename bundle
UPDATE BUNDLE "users" SET NAME = "customers";
Use Case: Schema refactoring for better naming conventions.
-- Create relationship: Customers → Orders
UPDATE BUNDLE "customers"
ADD RELATIONSHIP (
"1toMany",
"customers",
"DocumentID",
"orders",
"customer_id"
);
-- Create relationship: Orders → OrderItems
UPDATE BUNDLE "orders"
ADD RELATIONSHIP (
"1toMany",
"orders",
"DocumentID",
"order_items",
"order_id"
);
-- Create relationship: Products → OrderItems
UPDATE BUNDLE "products"
ADD RELATIONSHIP (
"1toMany",
"products",
"DocumentID",
"order_items",
"product_id"
);
Use Case: Setting up complete e-commerce relational structure.
Enables queries like:
SELECT * FROM "customers"
JOIN "orders" ON customers.DocumentID = orders.customer_id
JOIN "order_items" ON orders.DocumentID = order_items.order_id
JOIN "products" ON order_items.product_id = products.DocumentID;
-- Authors → Posts (1 to Many)
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"DocumentID",
"posts",
"author_id"
);
-- Posts → Comments (1 to Many)
UPDATE BUNDLE "posts"
ADD RELATIONSHIP (
"1toMany",
"posts",
"DocumentID",
"comments",
"post_id"
);
-- Categories → Posts (0 to Many - posts without category allowed)
UPDATE BUNDLE "categories"
ADD RELATIONSHIP (
"0toMany",
"categories",
"DocumentID",
"posts",
"category_id"
);
-- Posts ↔ Tags (Many to Many)
UPDATE BUNDLE "posts"
ADD RELATIONSHIP (
"ManyToMany",
"posts",
"DocumentID",
"tags",
"tag_id"
);
Use Case: Content management system with complex relationships.
-- Short form with defaults
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"", -- Defaults to "DocumentID"
"books",
"" -- Defaults to "authorsID"
);
-- Equivalent long form
UPDATE BUNDLE "authors"
ADD RELATIONSHIP (
"1toMany",
"authors",
"DocumentID",
"books",
"authorsID"
);
Use Case: Quick relationship setup with conventional field names.
-- Add new field and create relationship
UPDATE BUNDLE "users"
SET (
{ADD "role_id" = "role_id", "int", TRUE, FALSE, 1}
);
UPDATE BUNDLE "users"
ADD RELATIONSHIP (
"1toMany",
"roles",
"DocumentID",
"users",
"role_id"
);
Use Case: Adding role-based access control to existing user system.
-- Remove deprecated fields
UPDATE BUNDLE "products"
SET (
{REMOVE "old_price" = "", "", FALSE, FALSE, NULL},
{REMOVE "legacy_sku" = "", "", FALSE, FALSE, NULL}
);
-- Add new fields
UPDATE BUNDLE "products"
SET (
{ADD "current_price" = "current_price", "float", TRUE, FALSE, 0.0},
{ADD "sale_price" = "sale_price", "float", FALSE, FALSE, NULL},
{ADD "discount_percent" = "discount_percent", "float", FALSE, FALSE, 0.0}
);
Use Case: Migrating from old schema to new pricing structure.
✅ CORRECT: UPDATE BUNDLE "users" SET NAME = "customers";
❌ INCORRECT: UPDATE BUNDLE users SET NAME = customers;
✅ GOOD: {ADD "email_verified" = "email_verified", "bool", FALSE, FALSE, FALSE}
❌ AVOID: {ADD "flag1" = "flag1", "bool", FALSE, FALSE, FALSE}
Choose the correct relationship type for your data model:
✅ CORRECT: 1 customer → many orders (1toMany)
❌ WRONG: 1 order → many customers (doesn't make business sense)
✅ GOOD PATTERN:
- Source: "DocumentID"
- Destination: "<bundle_name>_id" or "<bundle_name>ID"
Examples:
- author_id, customer_id, product_id
- authorID, customerID, productID
After adding relationships, verify with a JOIN query:
UPDATE BUNDLE "authors" ADD RELATIONSHIP ("1toMany", "authors", "DocumentID", "books", "author_id");
-- Test it:
SELECT * FROM "authors" JOIN "books" ON authors.DocumentID = books.author_id;
Keep track of schema changes:
-- Good: Add comment explaining why
UPDATE BUNDLE "users"
SET (
{ADD "gdpr_consent" = "gdpr_consent", "bool", TRUE, FALSE, FALSE}
);
-- Added for GDPR compliance, 2025-01-15
When modifying fields:
✅ SAFE: {MODIFY "email" = "email", "string", TRUE, TRUE, ""}
-- Same type, adding unique constraint
❌ RISKY: {MODIFY "age" = "age", "string", TRUE, FALSE, ""}
-- Changing int to string might break existing data
When making multiple related changes, group them logically:
-- All related changes together
UPDATE BUNDLE "users"
SET (
{ADD "role_id" = "role_id", "int", TRUE, FALSE, 1},
{REMOVE "old_role" = "", "", FALSE, FALSE, NULL}
);
UPDATE BUNDLE "users"
ADD RELATIONSHIP ("1toMany", "roles", "DocumentID", "users", "role_id");
❌ ERROR:
UPDATE BUNDLE "nonexistent" SET NAME = "new_name";
Error Message:
bundle 'nonexistent' not found
Solution: Verify the bundle exists:
SHOW BUNDLES;
❌ ERROR:
UPDATE BUNDLE "users" ADD RELATIONSHIP ("1to1", "users", "id", "orders", "user_id");
Error Message:
invalid relationship type '1to1'. Valid types are: 0toMany, 1toMany, ManyToMany
Solution:
✅ CORRECT:
UPDATE BUNDLE "users" ADD RELATIONSHIP ("1toMany", "users", "DocumentID", "orders", "user_id");
Valid Types:
"1toMany""0toMany""ManyToMany"❌ ERROR:
UPDATE BUNDLE "users";
Error Message:
UPDATE BUNDLE must specify at least one operation: SET NAME, SET fields, or ADD RELATIONSHIP
Solution:
✅ CORRECT:
UPDATE BUNDLE "users" SET NAME = "customers";
❌ ERROR:
UPDATE BUNDLE "users"
SET (
{UPDATE "name" = "full_name", "string", TRUE, FALSE, ""}
);
Error Message:
invalid modification type 'UPDATE'. Valid types are: ADD, MODIFY, REMOVE
Solution:
✅ CORRECT:
UPDATE BUNDLE "users"
SET (
{MODIFY "name" = "full_name", "string", TRUE, FALSE, ""}
);
Valid Modification Types:
ADDMODIFYREMOVE❌ ERROR:
UPDATE BUNDLE "users"
SET (
{ADD "email" = "email", "string", TRUE, FALSE, ""}
);
-- But 'email' field already exists
Error Message:
field 'email' already exists in bundle 'users'
Solution:
Use MODIFY instead:
✅ CORRECT:
UPDATE BUNDLE "users"
SET (
{MODIFY "email" = "email", "string", TRUE, TRUE, ""}
);
❌ ERROR:
UPDATE BUNDLE "users"
SET (
{MODIFY "nonexistent" = "new_name", "string", TRUE, FALSE, ""}
);
Error Message:
field 'nonexistent' not found in bundle 'users'
Solution:
Use ADD for new fields:
✅ CORRECT:
UPDATE BUNDLE "users"
SET (
{ADD "new_field" = "new_field", "string", TRUE, FALSE, ""}
);
❌ ERROR:
UPDATE BUNDLE "users"
SET (
{ADD "age" = "age", "int"}
);
Error Message:
field definition must have all properties: modification type, name, new name, type, required, unique, default
Solution:
✅ CORRECT (all properties):
UPDATE BUNDLE "users"
SET (
{ADD "age" = "age", "int", FALSE, FALSE, 0}
);
❌ ERROR:
UPDATE BUNDLE "users" ADD RELATIONSHIP "1toMany", "users", "id", "orders", "user_id";
Error Message:
expected '(' after RELATIONSHIP
Solution:
✅ CORRECT (wrapped in parentheses):
UPDATE BUNDLE "users" ADD RELATIONSHIP ("1toMany", "users", "DocumentID", "orders", "user_id");
After updating a bundle, verify the changes:
SHOW BUNDLE "users";
Expected Output:
Bundle: users
Fields:
- id (int, required, unique)
- full_name (string, required) -- renamed from 'name'
- email (string, required, unique)
- age (int, optional) -- newly added
-- Query using the relationship
SELECT * FROM "authors"
JOIN "books" ON authors.DocumentID = books.author_id;
| Operation | Syntax | Example |
|---|---|---|
| Rename Bundle | UPDATE BUNDLE "old" SET NAME = "new" |
UPDATE BUNDLE "users" SET NAME = "customers" |
| ADD Field | SET ({ADD "field" = "field", "type", req, uniq, default}) |
{ADD "age" = "age", "int", FALSE, FALSE, 0} |
| MODIFY Field | SET ({MODIFY "old" = "new", "type", req, uniq, default}) |
{MODIFY "name" = "full_name", "string", TRUE, FALSE, ""} |
| REMOVE Field | SET ({REMOVE "field" = "", "", FALSE, FALSE, NULL}) |
{REMOVE "old_field" = "", "", FALSE, FALSE, NULL} |
| 1toMany | ADD RELATIONSHIP ("1toMany", src, src_fld, dest, dest_fld) |
("1toMany", "users", "DocumentID", "orders", "user_id") |
| 0toMany | ADD RELATIONSHIP ("0toMany", src, src_fld, dest, dest_fld) |
("0toMany", "categories", "DocumentID", "products", "category_id") |
| ManyToMany | ADD RELATIONSHIP ("ManyToMany", src, src_fld, dest, dest_fld) |
("ManyToMany", "students", "DocumentID", "courses", "course_id") |
For more information:
Last updated: November 20, 2025 🚀