Skip to main content

Import Data

RushDB accepts raw data — JSON objects, nested trees, flat arrays, or CSV — and turns it into a fully typed, linked graph. No schema definitions, no migrations, no manual relationship wiring.

How Nested Data Becomes a Graph

When you import a nested JSON object, RushDB walks the structure with a breadth-first search (BFS) algorithm. Each nested object becomes a separate record, linked to its parent by a relationship.

{
"title": "Inception",
"rating": 8.8,
"ACTOR": [
{ "name": "Leonardo DiCaprio", "country": "USA" },
{ "name": "Ken Watanabe", "country": "Japan" }
]
}

This single call produces 3 records (MOVIE + ACTOR × 2) with relationships between them, plus typed properties on each — all inferred automatically.

The ingestion pipeline

  1. Parse — BFS walk. Each nested object becomes a separate record.
  2. Type inference — Every value is classified as string, number, boolean, datetime, or null.
  3. Label assignment — Top-level records use the label you provide. Nested objects derive their label from the parent key name (e.g., key "engine" → label Engine).
  4. Relationship creation — Parent → child records are linked with default relationships (__RUSHDB__RELATION__DEFAULT__).

Import Nested JSON

db.records.create_many() — pass a dict with nested structure.

db.records.create_many(
label="MOVIE",
data={
"title": "Inception",
"rating": 8.8,
"ACTOR": [
{"name": "Leonardo DiCaprio", "country": "USA"},
{"name": "Ken Watanabe", "country": "Japan"}
]
}
)
# MOVIE → ACTOR × 2: all created and linked automatically

Infer the label from a single top-level key:

db.records.create_many(
data={"ITEM": [
{"name": "Sprocket", "weight": 1.2},
{"name": "Cog", "weight": 0.7}
]}
)
# label inferred as 'ITEM'

Import Flat Arrays

Use this for flat, row-like data (no nested objects inside items). This is the fastest path for CSV-shaped data.

db.records.create_many() — pass a list.

db.records.create_many(
label="ACTOR",
data=[
{"name": "Leonardo DiCaprio", "country": "USA"},
{"name": "Ken Watanabe", "country": "Japan"}
],
options={"suggestTypes": True}
)

Import CSV

db.records.import_csv()

with open("actors.csv") as f:
csv_content = f.read()

db.records.import_csv(
label="ACTOR",
data=csv_content,
options={"suggestTypes": True, "returnResult": False},
parse_config={"header": True, "dynamicTyping": True}
)

CSV parseConfig options

OptionDefaultDescription
delimiter,Column separator
headertrueFirst row is header
skipEmptyLinestrueIgnore blank rows ("greedy" also skips whitespace-only lines)
dynamicTypinginherits from suggestTypesAuto-convert numbers and booleans
quoteChar"Quote character
escapeChar"Escape character
newlineautoExplicit newline sequence override

Upsert during Import

All import methods support upsert via mergeBy and mergeStrategy.

# Append — update matched records, preserve other fields
db.records.create_many(
label="ACTOR",
data=actors,
options={"mergeBy": ["name"], "mergeStrategy": "append"}
)

# Rewrite — replace all properties for matched records
db.records.import_csv(
label="ACTOR",
data=csv_content,
options={"mergeBy": ["name"], "mergeStrategy": "rewrite"}
)

Merge strategies

StrategyBehaviour
append (default)Add / update incoming fields; preserve all other existing fields
rewriteReplace all fields with incoming data; unmentioned fields are removed

mergeBy behaviour

mergeBy valueMatch behaviour
["field"]Match only on listed fields
[] or omittedMatch on ALL incoming property keys

Import Options

OptionTypeDefaultDescription
suggestTypesbooleantrueInfer property types automatically. Set to false to store all values as strings.
convertNumericValuesToNumbersbooleanfalseConvert string numbers to number type
capitalizeLabelsbooleanfalseUppercase all auto-derived label names
relationshipTypestring__RUSHDB__RELATION__DEFAULT__Relationship type for nested links
returnResultbooleanfalseReturn created records in the response. Ignored for imports >1 000 records (summary returned instead).
mergeBystring[]undefinedProperty names to match existing records on. If omitted with mergeStrategy present, all incoming keys are used.
mergeStrategystringappendappend or rewrite. Providing either option triggers upsert semantics.

Method Quick Reference

ScenarioPythonTypeScriptREST
Flat rowscreate_many(label, data=[…])createMany({label, data:[…]})POST /import/json with array
Nested JSONcreate_many(label, data={…})importJson({label, data:{…}})POST /import/json with object
CSV stringimport_csv(label, data=csv)importCsv({label, data:csv})POST /import/csv

See also