Write queries
NamiDB’s write side is Cypher-native. Every write call inside the Python / Rust / HTTP clients commits as it returns — WAL append + manifest CAS happen synchronously.
CREATE
CREATE (a:Person {name: 'Alice', age: 30})Allocates a fresh internal NodeId. To control the NodeId explicitly,
pass _id:
CREATE (a:Person {_id: $uuid, name: 'Alice'})Edges
MATCH (a:Person {_id: $a}), (b:Person {_id: $b})CREATE (a)-[r:KNOWS {since: 2020}]->(b)The pattern requires both endpoints to be bound; NamiDB does not
auto-create endpoints in a CREATE for an edge.
MERGE
MERGE is the upsert primitive — match if exists, create otherwise.
MERGE (p:Person {_id: $uuid})ON CREATE SET p.created_at = datetime()ON MATCH SET p.last_seen = datetime()MATCH (a:Person {_id: $a}), (b:Person {_id: $b})MERGE (a)-[r:KNOWS]->(b)ON CREATE SET r.since = datetime()SET
MATCH (p:Person {_id: $id})SET p.age = $age, p.last_seen = datetime()Bulk update via map:
MATCH (p:Person {_id: $id})SET p += {age: $age, country: $country, last_seen: datetime()}DELETE / DETACH DELETE
MATCH (p:Person {_id: $id}) DELETE p // errors if p has edgesMATCH (p:Person {_id: $id}) DETACH DELETE p // deletes p + its edgesREMOVE
MATCH (p:Person {_id: $id}) REMOVE p.old_fieldMATCH (n:Person) REMOVE n:Pending // remove a labelCombining writes with reads
MATCH (a:Person {_id: $a})WITH aMATCH (b:Person {_id: $b})CREATE (a)-[r:KNOWS {since: 2020}]->(b)RETURN rBulk inserts (Python)
For high-volume ingestion, prefer the bulk staging APIs over per-row
CREATE:
import uuidimport namidb as tg
client = tg.Client("s3://my-bucket?ns=prod®ion=us-east-1")
client.merge_nodes( "Person", [{"id": str(uuid.uuid4()), "name": f"p{i}", "age": 20 + i} for i in range(10_000)],)client.merge_edges( "KNOWS", [{"src": "uuid-a", "dst": "uuid-b", "since": 2020}],)client.commit() # WAL + manifest CASclient.flush() # memtable -> L0 SSTsThese stage into the current batch (same lifecycle as upsert_*) and
amortise a single tokio-runtime + mutex round-trip across thousands of
rows.