Ship Seed Data with a Solution
Goal
Make the rows a solution needs — reference data, configuration rows, a sample set — travel inside the solution package, so that importing the solution into an empty environment leaves it ready to use rather than ready to be filled in.
Prerequisites
- You are signed in with a maker (or platform administrator) role.
- The table whose rows should travel is a component of the solution, and the rows exist in the environment you export from.
Steps
- Open the table in Tables and go to the Views tab.
- Select New to open the View Designer.
- Enter a display name — for example,
Thresholds that ship— and a logical name after the publisher prefix, for exampleapproval_threshold_seed. - Set View type to Seed data, and choose what the rows are in Rows are:
- Configuration: rows the solution needs to work, such as approval thresholds or a list of regions. Every import brings them, Production included.
- Demonstration: rows that show the solution off, such as invented customers. An import brings them only when asked, and never into Production.
- Drag onto the grid header every field that should travel. Leave out what is this environment's rather than the row's — a committed amount, a last-run date, a counter.
- Add a filter if only some rows should travel — for example, Status equals Active. With no filter, every row travels.
- Select Save.
- Export the solution from the Solutions page. The package now carries one seed-data document for the table, holding the rows the view returned.
- Import the package into another environment. Configuration rows come with it. If it carries demonstration rows, the import asks first: tick Include demonstration data to bring them. When the import finishes, a message says how many rows were created, how many were updated, names any that were skipped, and says how many demonstration rows were left out.
Configuration always comes; demonstration only when asked
The Rows are choice on the Seed Data view decides what an import does with the rows.
| Configuration | Demonstration | |
|---|---|---|
| Is | what the solution needs to work: thresholds, regions, settings a script reads | what shows it off: invented customers, a year of sample history |
| An import | always brings it | brings it only when Include demonstration data is ticked |
| Production | yes | never: the box is disabled, and the platform refuses it |
Demonstration never reaches Production because rows imported there would sit among your customers' own with nothing to tell them apart, and uninstalling the solution would not remove them. Configuration always does because an environment without it does not work.
Choose Configuration only for rows that are the same everywhere the solution runs. A row an environment edits for itself is overwritten by the next import.
What happens behind the scenes
A Seed data view is never shown to anyone: it is a question the export asks. Its filter answers which rows, and its columns answer which fields. A table with several such views uses the one marked default, else the first by logical name.
Each row travels with its id, and the import upserts by that id: a row the target does not have is created with the same id; a row it already has is updated on the packaged columns only, and keeps every other value. Nothing is ever deleted. Because the id is the same in every environment, one seed row can point at another — a budget line at its programme — and the import writes the tables in the right order for that to work. A lookup at a row of the same table is filled in after every row exists.
Every row goes through the ordinary record write path: it is validated against the table, attributed to the import, checked against the target's lookups, and plugin steps on the table run on it — including a step the same solution brought.
What a seed row does not do is start a business process. A process that starts when a record is created is about somebody creating one; a seed row is the solution's picture of a table as it was left — a request already approved, one already rejected. Firing the process for every packaged row would start a run per row and let the process's own first step overwrite the status the row was shipped with. That also means a row seeded in a waiting status has no task behind it: a package carries rows, not runs. If the demonstration needs a live task, raise a record in the imported environment — that one is routed.
A row the target refuses — most often a lookup at a record the target does not have — is skipped and named, by table, id and reason, rather than failing the import. The tables, forms and views have already landed by then, and an import that failed over one row would leave the environment half-imported.
Some things deliberately do not travel: the owner (users are per tenant), the created and modified stamps and the row version (they are the target's), and File and Image columns (their bytes live in the source environment). Autonumber columns are minted by the target.
Troubleshooting
- The import says a row was skipped. Read the reason — it is the same sentence a form would show. A lookup at a record that does not exist means the target lacks a row the package assumed; add that table's rows to the package, or the record to the target.
- A row I edited in the target was overwritten. That is what re-importing does: the packaged columns are the solution's. Keep environment-specific values out of the seed view's columns.
- The export refuses with "returns N rows". A package carries at most 10,000 rows per table. Narrow the view's filter — seed data is reference data, not history — or load the rows with a CSV import instead.
- Nothing travelled. Check that the view's type is Seed data and that it is on a table the solution contains. If its rows are Demonstration, check that Include demonstration data was ticked on the import.
- The Include demonstration data box is greyed out. The environment is a Production environment, where demonstration data is never imported. Configuration rows still come.
- Rows the solution needs did not reach Production. Their Seed Data view says Demonstration. Change it to Configuration, export the solution again, and import it.
- Uninstalling the solution left the rows behind. Rows in a table the solution owns go with the table. Rows it added to a table that belongs to another solution stay, because the table stays.