# Data import and export

The Comind.work CLI provides commands for bulk-loading records into a workspace and exporting app definitions back to local files. This guide covers the practical details of each workflow.

## Importing records[​](#importing-records "Direct link to Importing records")

### From CSV[​](#from-csv "Direct link to From CSV")

Use `npx comind createRecords` to load records from a CSV file. Each row becomes one record; column headers must match the field database names (with the `c_` prefix) defined in your app schema.

**Example CSV file** (`contacts.csv`):

```
c_name,c_email,c_company,c_phone
Alice Johnson,alice@example.com,Acme Corp,+1-555-0101
Bob Martinez,bob@martinez.io,Globex Inc,+1-555-0142
Carol Liu,carol.liu@example.org,Initech,+1-555-0183
```

**Run the import:**

```
npx comind createRecords app-contact CMW --file contacts.csv
```

* `app-contact` - the app alias where records will be created
* `CMW` - the target workspace
* `--file contacts.csv` - path to the CSV file

On success the CLI prints the number of records created. Each row is inserted as a new record regardless of whether a matching record already exists - see [Handling duplicates with importRecords](#handling-duplicates-with-importrecords) if you need upsert behavior.

Field names

Column headers must use the field database name, not the display label. Run `npx comind pull <app-alias> <target-dir>` and inspect the generated field files to find the exact `c_` prefixed names. See [CLI reference](/developer-guide/reference/cli-reference.md) for more on `pull`.

### From JSON[​](#from-json "Direct link to From JSON")

The same command accepts a JSON file containing an array of objects. Each object follows the same `c_`-prefixed field naming convention.

**Example JSON file** (`contacts.json`):

```
[
  {
    "c_name": "Alice Johnson",
    "c_email": "alice@example.com",
    "c_company": "Acme Corp",
    "c_phone": "+1-555-0101"
  },
  {
    "c_name": "Bob Martinez",
    "c_email": "bob@martinez.io",
    "c_company": "Globex Inc",
    "c_phone": "+1-555-0142"
  },
  {
    "c_name": "Carol Liu",
    "c_email": "carol.liu@example.org",
    "c_company": "Initech",
    "c_phone": "+1-555-0183"
  }
]
```

```
npx comind createRecords app-contact CMW --file contacts.json
```

JSON is useful when field values contain commas or newlines that would complicate CSV formatting.

### Handling duplicates with importRecords[​](#handling-duplicates-with-importrecords "Direct link to Handling duplicates with importRecords")

When you need to update existing records and create only the ones that do not exist yet, use `npx comind importRecords`. It performs an upsert - matching incoming rows against existing records by one or more key fields.

```
npx comind importRecords app-contact CMW --file contacts.csv --keyFields c_email
```

**How matching works:**

| Scenario                                        | Result                                             |
| ----------------------------------------------- | -------------------------------------------------- |
| A record with the same `c_email` already exists | The existing record is updated with the new values |
| No record matches the `c_email`                 | A new record is created                            |

You can specify multiple key fields separated by commas:

```
npx comind importRecords app-contact CMW --file contacts.csv --keyFields c_email,c_company
```

In this case, both fields must match for the CLI to treat a row as an update rather than a new record.

**Realistic example** - you receive an updated contact list each week. Some contacts are new, some have changed phone numbers. Running `importRecords` with `--keyFields c_email` ensures existing contacts are updated in place while new ones are added:

```
npx comind importRecords app-contact CMW --file weekly-contacts-export.csv --keyFields c_email
```

This is safe to re-run - when key fields are set, the command is idempotent. Running it twice with the same input produces the same result.

## Exporting data[​](#exporting-data "Direct link to Exporting data")

### Dumping app definitions[​](#dumping-app-definitions "Direct link to Dumping app definitions")

Use `npx comind dump` to export a running app's schema - fields, actions, layouts, and settings - into TypeScript source files on your local machine.

```
npx comind dump default-app-contact apps-dev/app-contact
```

* `default-app-contact` - the app identifier in the workspace
* `apps-dev/app-contact` - the local directory where files will be written

The output follows the standard [package structure](/developer-guide/app-architecture/package-structure.md):

```
apps-dev/app-contact/
  fields/
    c_name.ts
    c_email.ts
    c_company.ts
    c_phone.ts
  actions/
  views/
  settings/
  package.json
```

This is useful for:

* **Backup** - capturing the current state of an app before making changes
* **Migration** - converting a legacy app to the v2 package structure
* **Inspection** - reviewing what fields and actions are configured

The `dumpLint` variant runs ESLint auto-fix on the generated files for cleaner output:

```
npx comind dumpLint default-app-contact apps-dev/app-contact
```

See the [CLI reference](/developer-guide/reference/cli-reference.md) for more details on `dump` and `dumpLint`.

### Exporting records[​](#exporting-records "Direct link to Exporting records")

Record export is not available through the CLI. To export records as data:

* **Web UI** - open any list view in Comind.work and use the CSV export option from the list toolbar
* **REST API** - query records programmatically and write the results to a file in any format you need

## Tips[​](#tips "Direct link to Tips")

* Always test imports on a development workspace first before running against production.
* Use exact field database names as column headers - run `npx comind pull` to see what names your app uses.
* Large imports (1,000+ records) may take several minutes. The CLI processes rows sequentially.
* `importRecords` is idempotent when `keyFields` are set - safe to re-run without creating duplicates.
* If a CSV file uses a semicolon delimiter or non-UTF-8 encoding, convert it to standard comma-separated UTF-8 before importing.

## Related[​](#related "Direct link to Related")

* [CLI reference](/developer-guide/reference/cli-reference.md) - full command syntax for `createRecords`, `importRecords`, `dump`, and other CLI commands
* [Import and export workflows](/admin-guide/workspace-admin/import-export-workflows.md) - admin-guide coverage of data import and export from the workspace admin perspective
