Schema Editing
Added in version vNext.
Reads and changes schemas (document types) and their properties, one small command per change: rename a property, add a field, change a type, edit pick list options.
These commands are built for agents and scripts. People editing schemas by hand should use the schema editor in the UI.
MCP Server - the same operations as
schema_*tools
Commands
All commands take --dataBase (file path or remote URL) and --credentials (for remote sources).
Every write takes --dryRun, which validates and prints the same summary without writing.
Command |
Parameters |
MCP tool |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Option values and defaults:
--schemaType(CREATE,UPDATE):Normal(default),Component(always embedded in other documents),Settings(one document only) orUnion.--idGenerator(CREATE,UPDATE): how theIdof new documents is produced.None(default, you supply every Id),ObjectId,Guid,Sequence(per schema) orGlobalSequence(across the project).--cascade(DELETE): what happens to properties of other schemas that reference or embed the deleted schema, including shared properties.Deny(default) refuses the delete and lists them;Cascaderemoves them along with the schema.--allowDataLoss: needed only when the edited schema has documents (embedded ones included). On an empty schema every command runs without it.--requirement:None(default),NotNullorNotEmpty.--uniqueness:None(default),UniqueorUniqueInCollection.
Rules shared by all commands:
--schemaand--propertytake exact names or Ids.GET,ADD,UPDATE,CHANGETYPEandREMOVEaccept a space-separated list (--schema Quest QuestStep) or'*'alone for all. Other commands take exactly one. On writes'*'skips theIdproperty; onGETit lists it too. Schema'*'never selects the system schemas (Schema,SchemaProperty,ProjectSettings).There are no patterns:
Quest*is an unknown name, and!exclusions are not supported. Every listed name must exist, otherwise nothing is written and the error names the missing ones.Quote
'*': a bare*is expanded to file names by the shell before Charon sees it.The
Idproperty cannot be renamed, removed or moved.Unknown options fail these commands (
--dry-runinstead of--dryRunis an error, not a silent real write). OtherDATAcommands keep ignoring unknown options.Write output is a short summary: targets, changes, affected document count and warnings. Errors go to stderr with exit code
2.
Type Grammar
--type takes one quoted string <DataType> [size] [schema] [options]. GET prints types in the same
form, so a printed type passed back to CHANGETYPE changes nothing.
Form |
Meaning |
|---|---|
|
optional maximum length |
|
no arguments |
|
size in bytes, 1-8; omitted size is 4 |
|
referenced schema name, required |
|
embedded schema name, required |
|
optional maximum item count before the schema name |
|
options; omitted values are assigned 0, 1, 2… |
|
options; omitted values are assigned as powers of two |
The type fully determines size and reference target: Integer 8 changed to Text becomes an unlimited
Text, not Text 8. Formula is not supported by the grammar.
Pick List Changes
UPDATEPICKLIST edits options partially. Put all changes in one quoted --changes value; unquoted, the
shell would split them.
Token |
Meaning |
|---|---|
|
add an option |
|
add with the next free value (next free power of two for |
|
remove by name |
|
remove and assert the current value; fails when it differs (stale view guard) |
Removals apply before additions. A removal and an addition with the same value is a rename
(-HP=2 +HealthPoints=2); documents store values, so nothing else changes. The same name with a new value is a
renumber (-A=1 +A=3). Stored values are never migrated: after a renumber or removal they no longer match an
option, so both need --allowDataLoss while the schema has documents.
Data Loss Guard
CHANGETYPE with documents (embedded ones included) rejects changes to or from Document,
DocumentCollection, Reference, ReferenceCollection, Formula, and from LocalizedText.
These are allowed while the schema has no documents.
Lossy changes need --allowDataLoss while documents exist: text to number, logical, date, time or pick list;
Number to Integer; number to logical, date or time and back; any type to a pick list; a smaller size or text limit, or a limit added to unlimited
text; a new reference target; options dropped by a full option list replacement. The decision uses the change and
the document count only. Values that do not convert stay as they are and leave documents invalid until edited.
A changed type drops pick.* entries the new type does not use and formula entries (param.*,
resultType, knownType). For a shared property, documents of every schema using it count.
To check that a schema is empty, run DATA LIST with --path '*' --take 0.
Read Format
One line per schema and property, labels equal to the write parameter names, defaults omitted. Property attributes
print in the order Property, Type, Requirement, Uniqueness, Auto-Generated, Default,
Shared, then with --details DisplayName and Description.
Free text is JSON-quoted and single-line. Without --details a Default longer than 80 characters is cut and
ends in …; such a value is truncated and must not be passed back.
Examples
The examples run against a copy of the RPG sample project.
GET - schema with its properties:
dnx dotnet-charon -- DATA SCHEMA GET --dataBase rpg.json --schema Quest
#> Schema: Quest, IdGenerator: ObjectId, Group: Story
#> - Property: Id, Type: Text 24, Requirement: NotNull, Uniqueness: Unique, Auto-Generated
#> - Property: Title, Type: LocalizedText 200, Requirement: NotEmpty
#> - Property: Difficulty, Type: PickList Easy=0 Normal=1 Hard=2, Default: "Normal"
#> - Property: Giver, Type: Reference Hero
CREATE:
dnx dotnet-charon -- DATA SCHEMA CREATE --dataBase rpg.json --name Quest --idGenerator ObjectId --group Story
#> Target: Quest
#> Change: created schema Quest
RENAME (dry run):
dnx dotnet-charon -- DATA SCHEMA RENAME --dataBase rpg.json --schema Disease --newName Illness --dryRun
#> Dry run: nothing was written.
#> Target: Disease
#> Change: renamed schema Disease to Illness
#> Documents: 6 (incl. embedded)
UPDATE:
dnx dotnet-charon -- DATA SCHEMA UPDATE --dataBase rpg.json --schema Quest --displayName "Quests" --icon scroll
#> Target: Quest
#> Change: updated schema Quest: DisplayName, Icon scroll
DELETE - an empty schema needs no extra options:
dnx dotnet-charon -- DATA SCHEMA DELETE --dataBase rpg.json --schema Quest
#> Target: Quest
#> Change: deleted schema Quest
#> Documents: 0 (incl. embedded)
A schema with documents needs --allowDataLoss; its documents are deleted with it:
dnx dotnet-charon -- DATA SCHEMA DELETE --dataBase rpg.json --schema Quirk
#> Schema `Quirk` has 8 documents (incl. embedded). Pass allowDataLoss to delete them with the schema.
dnx dotnet-charon -- DATA SCHEMA DELETE --dataBase rpg.json --schema Quirk --allowDataLoss
#> Target: Quirk
#> Change: deleted schema Quirk
#> Documents: 8 (incl. embedded)
A schema other schemas reference is refused until --cascade Cascade allows removing those properties:
dnx dotnet-charon -- DATA SCHEMA DELETE --dataBase rpg.json --schema Item --allowDataLoss
#> Schema `Item` is referenced by property CurioCleansingOption.Item, property ItemWithCount.Item,
#> property Provision.Item, property Trinket.Item. Set cascade to Cascade to remove these properties too.
dnx dotnet-charon -- DATA SCHEMA DELETE --dataBase rpg.json --schema Item --allowDataLoss --cascade Cascade
#> Target: Item
#> Change: deleted schema Item
#> Change: removed property CurioCleansingOption.Item
#> Change: removed property ItemWithCount.Item
#> Change: removed property Provision.Item
#> Change: removed property Trinket.Item
#> Documents: 39 (incl. embedded)
PROPERTY GET:
dnx dotnet-charon -- DATA SCHEMA PROPERTY GET --dataBase rpg.json --schema Monster --property Name Type
#> Property: Name, Type: LocalizedText 120, Requirement: NotNull
#> Property: Type, Type: PickList Human=1 Beast=2 Unholy=3 Eldritch=4 Corpse=5 Carpentry=6 Crockery=7 Ironwork=8 Thatchery=9 Cosmic=10, Requirement: NotNull, Default: "1"
PROPERTY ADD:
dnx dotnet-charon -- DATA SCHEMA PROPERTY ADD --dataBase rpg.json --schema Quest \
--name Difficulty --type "PickList Easy Normal Hard" --default Normal
#> Target: Quest.Difficulty
#> Change: added property Quest.Difficulty (PickList Easy=0 Normal=1 Hard=2)
PROPERTY RENAME:
dnx dotnet-charon -- DATA SCHEMA PROPERTY RENAME --dataBase rpg.json --schema Quest --property Giver --newName QuestGiver
#> Target: Quest.Giver
#> Change: renamed property Quest.Giver to QuestGiver
#> Documents: 0 (incl. embedded)
The rename keeps the property Id, so stored values move with it. It warns when the old name still appears in the schema’s display text template or a formula specification; those are not rewritten.
PROPERTY UPDATE:
dnx dotnet-charon -- DATA SCHEMA PROPERTY UPDATE --dataBase rpg.json --schema Quest --property Difficulty \
--requirement NotNull --after Id
#> Target: Quest.Difficulty
#> Change: updated property Quest.Difficulty: Requirement NotNull, moved after Id
PROPERTY UPDATESPECIFICATION - the only raw key=value surface; --preservePickList and
--preserveFormula keep the entries the type system owns:
dnx dotnet-charon -- DATA SCHEMA PROPERTY UPDATESPECIFICATION --dataBase rpg.json --schema Quest \
--property Difficulty --specification "editor=radio" --preservePickList
#> Target: Quest.Difficulty
#> Change: set specification of Quest.Difficulty
PROPERTY UPDATEPICKLIST:
dnx dotnet-charon -- DATA SCHEMA PROPERTY UPDATEPICKLIST --dataBase rpg.json --schema Quest \
--property Difficulty --changes "-Hard=2 +Heroic=2 +Legendary"
#> Target: Quest.Difficulty
#> Change: renamed option Hard to Heroic (value 2)
#> Change: added option Legendary (value 3)
#> Documents: 0 (incl. embedded)
PROPERTY CHANGETYPE - a lossy change with documents needs --allowDataLoss:
dnx dotnet-charon -- DATA SCHEMA PROPERTY CHANGETYPE --dataBase rpg.json --schema Hero \
--property ProvisionsCount --type "Integer 2" --dryRun
#> `Hero.ProvisionsCount` has 3 documents (incl. embedded) and the change may lose data: `Integer 4` → `Integer 2`
#> shrinks the size from 4 to 2 bytes. Pass allowDataLoss to proceed; values that do not convert stay as they are
#> and leave documents invalid until edited.
dnx dotnet-charon -- DATA SCHEMA PROPERTY CHANGETYPE --dataBase rpg.json --schema Hero \
--property ProvisionsCount --type "Integer 2" --allowDataLoss --dryRun
#> Dry run: nothing was written.
#> Target: Hero.ProvisionsCount
#> Change: changed type of Hero.ProvisionsCount from `Integer 4` to `Integer 2`
#> Documents: 3 (incl. embedded)
#> Warning: Hero.ProvisionsCount: `Integer 4` → `Integer 2` shrinks the size from 4 to 2 bytes
PROPERTY REMOVE:
dnx dotnet-charon -- DATA SCHEMA PROPERTY REMOVE --dataBase rpg.json --schema Quest --property QuestGiver
#> Target: Quest.QuestGiver
#> Change: removed property Quest.QuestGiver
#> Documents: 0 (incl. embedded)
See also
DATA LIST SCHEMAS - the raw
Schemacollection documents