Seed Data
Seed data is how Scipio gets rows into a database. A seed data file is an XML file with one element per row: the element
name is the entity, the attributes are the fields. A component registers its files under a reader name, and the
load-data command writes the files of the readers you ask for into the database.
Everything that a fresh database needs comes this way: enumerations and status items, units, security groups and their permissions, the types of the data model, a store with its website and catalog, and the products of a demo shop.
A seed data file#
<?xml version="1.0" encoding="UTF-8"?>
<entity-engine-xml>
<ProductCategory productCategoryId="AT_COATS" productCategoryTypeId="CATALOG_CATEGORY" categoryName="Coats"/>
<ProductCategoryRollup productCategoryId="AT_COATS" parentProductCategoryId="STORE_ROOT" fromDate="2026-01-01 00:00:00.0" sequenceNum="1"/>
<Product productId="AT-1001" productTypeId="FINISHED_GOOD" primaryProductCategoryId="AT_COATS"
productName="Long wool coat" description="An unlined coat in heavy wool, cut long."/>
<ProductPrice productId="AT-1001" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="EUR"
productStoreGroupId="_NA_" fromDate="2026-01-01 00:00:00.0" price="480.00"/>
<ProductCategoryMember productCategoryId="AT_COATS" productId="AT-1001" fromDate="2026-01-01 00:00:00.0"/>
</entity-engine-xml>- The root element is
entity-engine-xml. - Write the rows in dependency order: a row comes after the rows that its foreign keys point to.
- Dates use the format
yyyy-MM-dd HH:mm:ss.S. - Long text goes into a child element instead of an attribute:
<Product productId="..."><longDescription>...</longDescription></Product>.
What a load does with a row#
load-data looks each row up by its primary key:
- No row with that key: it creates the row.
- A row with that key: it updates only the fields that the file names and that differ. Fields that the file does not name keep their values.
So a later file can change a few fields of a row that an earlier file created. For example, a store file can set the
theme of an existing store with <ProductStore productStoreId="STORE" visualThemeId="SHOP_ATELIER"/>, and the other
fields of the store stay as they are. A load does not delete rows.
Readers#
The entity engine configuration (framework/entity/config/entityengine.xml) lists the reader names:
| Reader | What it holds |
|---|---|
tenant | The rows of the master database of a multi-store installation (tenants, their data sources and host names) |
seed | What every installation needs: types, enumerations, status items, units, security groups and permissions |
seed-initial | Rows that the first load creates and that people change later (for example the first admin login) |
demo | The demo data of each application |
ext | Your own data that every installation of your project needs |
ext-test | Data for tests |
ext-demo | Demo data that builds on the demo data of several applications; it loads last |
A new reader name is a change of entityengine.xml. For data that only some databases get, use the file argument
below instead of a new reader.
Register a file in a component#
The component file (scipio-component.xml, or scipio-theme.xml for a theme) names each data file with its reader:
<entity-resource type="data" reader-name="seed" loader="main" location="data/MyComponentSeedData.xml"/>
<entity-resource type="data" reader-name="demo" loader="main" location="data/MyComponentDemoData.xml"/>Put the files in the data/ folder of the component. Within one reader the component load order decides which files
load first, and within a file the order of the rows.
Permissions are seed data too. A component brings its SecurityPermission and SecurityGroupPermission rows in a
seed file; it does not grant them in code at start-up.
Load#
From the root of the installation:
| Command | What it loads |
|---|---|
./gradlew loadSeed | The readers seed and seed-initial |
./gradlew loadDemo | The readers seed, seed-initial, demo, ext and ext-demo |
./gradlew loadDemo -PloadReaders=seed,ext | Only the readers you name |
./gradlew loadSeed -PloadComponent=product | The readers of one component |
The Gradle tasks start load-data of the server. You can also give load-data its arguments directly:
| Argument | Meaning |
|---|---|
readers=seed,ext | The readers to load |
component=name | Only the files of this component |
file=path/to/File.xml | This file only (with no readers, no reader loads) |
dir=path/to/folder | Every XML file of this folder |
delegator=default#TENANT_ID | The database of one tenant instead of the default database |
timeout=7200 | The transaction timeout in seconds |
createfks | Create a placeholder row for a missing foreign key |
maintainTxs | Keep the transaction time stamps of the file |
Load data while the server is stopped. A running server keeps rows in its entity cache and does not see the change until it restarts.
To load one XML document by hand, use Admin › Import/Export › XML Data Import (Import / Export ).
Data for one store#
In a multi-store installation each store has its own database. Data that belongs to one store, for example the catalog
and products of a demo shop, is a seed data file of its own. It is not registered under a reader that every database
loads. Load it into that store’s database with the file and delegator arguments:
load-data file=components/demo-stores/data/atelier/AtelierStoreData.xml delegator=default#ATELIERExport data as seed data#
Admin › Import/Export › XML Data Export writes the rows of the entities you choose as an entity-engine-xml file.
That file loads again with load-data file=..., so an export is a quick way to start a seed data file from a database
that you filled by hand.