Insert rows reference

This Astra DB Serverless feature is currently in public preview. Development is ongoing, and the features and functionality are subject to change. Astra DB Serverless, and the use of such, is subject to the DataStax Preview Terms.

A row represents a single record of data in a table in a Astra DB Serverless database. You use the Table class to work with rows through the Data API clients. For instructions to get a Table object, see Work with tables.

For general information about working with rows, including common operations and operators, see Work with rows.

Prerequisites

Required client version

The Data API tables commands are available through HTTP and the clients. If you use a client, tables commands are available only in client versions 2.0-preview or later. For more information, see Data API client upgrade guide.

Insert a row

Insert a new row in a table.

If a row with the described primary key already exists in the table, the row will be overwritten with the specified column values. Unspecified columns will remain unchanged.

You can use this command to insert a row in an existing CQL table, but the Data API does not support all CQL data types or modifiers. For more information, see Column data types.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Insert a row with values specified for all columns:

insert_result = my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        "score": 18,
        "when": DataAPITimestamp.from_string("2024-11-28T11:30:00Z"),
        "winner": "Victor",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
        ]),
    },
)

Insert a row with values specified for some columns and unspecified columns set to null:

my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "winner": "Victor Vector",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
            UUID("0193539a-2880-8875-9f07-222222222222"),
        ]),
    },
)

Parameters:

Name Type Summary

row

dict

Defines the row to insert. Contains key-value pairs for each column in the table. At minimum, primary key values are required. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

general_method_timeout_ms

int

A timeout, in milliseconds, to impose on the underlying API request. If not provided, the Table defaults apply. This parameter is aliased as request_timeout_ms and timeout_ms for convenience.

Returns:

TableInsertOneResult - An instance of TableInsertOneResult detailing the primary key of the inserted row, both as a dictionary and an ordered tuple.

If any of the inserted columns are of the wrong datatype, or wrongly encoded, the entire insert will fail.

Example response (reformatted for clarity)
TableInsertOneResult(
  inserted_id={'match_id': 'match_0', 'round': 1},
  inserted_id_tuple=('match_0', 1),
  raw_results=...
)
Full example script
from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

from astrapy.constants import SortMode
from astrapy.info import (
    CreateTableDefinition,
    ColumnType,
)

my_table = database.create_table(
    "games",
    definition=(
        CreateTableDefinition.builder()
        .add_column("match_id", ColumnType.TEXT)
        .add_column("round", ColumnType.TINYINT)
        .add_vector_column("m_vector", dimension=3)
        .add_column("score", ColumnType.INT)
        .add_column("when", ColumnType.TIMESTAMP)
        .add_column("winner", ColumnType.TEXT)
        .add_set_column("fighters", ColumnType.UUID)
        .add_partition_by(["match_id"])
        .add_partition_sort({"round": SortMode.ASCENDING})
        .build()
    ),
)

# a full-row insert using astrapy's datatypes
from astrapy.data_types import (
    DataAPISet,
    DataAPITimestamp,
    DataAPIVector,
)
from astrapy.ids import UUID

insert_result = my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        "score": 18,
        "when": DataAPITimestamp.from_string("2024-11-28T11:30:00Z"),
        "winner": "Victor",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
        ]),
    },
)
insert_result.inserted_id
# {'match_id': 'match_0', 'round': 1}
insert_result.inserted_id_tuple
# ('match_0', 1)

# a partial-row (which in this case overwrites some of the values)
my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "winner": "Victor Vector",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
            UUID("0193539a-2880-8875-9f07-222222222222"),
        ]),
    },
)
# TableInsertOneResult(inserted_id={'match_id': 'match_0', 'round': 1} ...

# another insertion demonstrating standard-library datatypes in values
import datetime

my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 2,
        "winner": "Angela",
        "score": 25,
        "when": datetime.datetime(
            2024, 7, 13, 12, 55, 30, 889,
            tzinfo=datetime.timezone.utc,
        ),
        "fighters": {
            UUID("019353cb-8e01-8276-a190-333333333333"),
        },
        "m_vector": [0.4, -0.6, 0.2],
    },
)
# TableInsertOneResult(inserted_id={'match_id': 'match_0', 'round': 2}, ...

Example:

# a full-row insert using astrapy's datatypes
from astrapy.data_types import (
    DataAPISet,
    DataAPITimestamp,
    DataAPIVector,
)
from astrapy.ids import UUID

insert_result = my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        "score": 18,
        "when": DataAPITimestamp.from_string("2024-11-28T11:30:00Z"),
        "winner": "Victor",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
        ]),
    },
)
insert_result.inserted_id
# {'match_id': 'match_0', 'round': 1}
insert_result.inserted_id_tuple
# ('match_0', 1)

# a partial-row (which in this case overwrites some of the values)
my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 1,
        "winner": "Victor Vector",
        "fighters": DataAPISet([
            UUID("0193539a-2770-8c09-a32a-111111111111"),
            UUID("0193539a-2880-8875-9f07-222222222222"),
        ]),
    },
)
# TableInsertOneResult(inserted_id={'match_id': 'match_0', 'round': 1} ...

# another insertion demonstrating standard-library datatypes in values
import datetime

my_table.insert_one(
    {
        "match_id": "match_0",
        "round": 2,
        "winner": "Angela",
        "score": 25,
        "when": datetime.datetime(
            2024, 7, 13, 12, 55, 30, 889,
            tzinfo=datetime.timezone.utc,
        ),
        "fighters": {
            UUID("019353cb-8e01-8276-a190-333333333333"),
        },
        "m_vector": [0.4, -0.6, 0.2],
    },
)
# TableInsertOneResult(inserted_id={'match_id': 'match_0', 'round': 2}, ...

For more information, see the Client reference.

Insert a row with only the primary keys specified and all other columns set to null:

await table.insertOne({ matchId: 'match_0', round: 1 });

Insert a row with values for all columns:

await table.insertOne({
  matchId: 'match_0',
  round: 1,
  score: 18,
  when: timestamp(),
  winner: 'Victor',
  fighters: new Set([
    uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'),
    uuid(4),
  ]),
  mVector: vector([0.2, -0.3, -0.5]),
});

Parameters:

Name Type Summary

row

Schema

Defines the row to insert. Contains key-value pairs for each column in the table. At minimum, primary key values are required. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

timeout?

WithTimeout

The client-side timeout for this operation.

Returns:

Promise<TableInsertOneResult<PKey>> - An object detailing the primary key of the inserted row, typed as inferred from the PKey of the table’s type, or Partial<RSchema> if it cannot be inferred.

If any of the inserted columns are of the wrong datatype, or wrongly encoded, the entire insert will fail.

Example response
{
  insertedId: { matchId: 'match_0', round: 1 },
}

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema, timestamp, uuid, vector } from '@datastax/astra-db-ts';

// Instantiate the client and connect to the database
const client = new DataAPIClient();
const db = client.db(process.env.CLIENT_DB_URL!, { token: process.env.CLIENT_DB_TOKEN! });

// Create table schema using bespoke Data API table definition syntax, and then infer the type.
// For information about table typing and definitions, see the documentation for createTable.
const TableDefinition = <const>{
  columns: {
    matchId: 'text'
    round: 'tinyint',
    mVector: { type: 'vector', dimension: 3 },
    score: 'int',
    when: 'timestamp',
    winner: 'text',
    fighters: { type: 'set', valueType: 'uuid' },
  },
  primaryKey: {
    partitionBy: ['matchId'],
    partitionSort: { round: 1 },
  },
} satisfies CreateTableDefinition;

type TableSchema = InferTableSchema<typeof TableDefinition>;
type TablePK = InferTablePrimaryKey<typeof TableDefinition>;

(async function () {
  // Create a table with the given TableSchema type if a 'games' table doesn't already exist
  const table = await db.createTable<TableSchema, TablePK>('games', { definition: TableDefinition, ifNotExists: true });

// Use insertOne and insertMany to insert rows into tables.
// Inserts are also upserts for tables.

// insertOne examples

  // Inserts a single row
  const res = await table.insertOne({
      matchId: 'match_0',
      round: 1,                                       // All non-varint/decimal numbers are represented as JS numbers
      score: 18,
      when: timestamp(),                              // Shorthand for new DataAPITimestamp(new Date())
      winner: 'Victor',
      fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
        uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
        uuid(4),                                      // Shorthand for UUID.v4()
      ]),
      mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for new DataAPIVector([0.2, -0.3, -0.5])
    });                                               // Use this instead of plain arrays to enable vector-specific optimizations

  // Returns primary key of type { id: string, time: DataAPITimestamp }
  const primaryKey = res.insertedId;
  console.log(primaryKey.matchId);

  // Inserts are also upserts in tables.
  // If the winner of round 1 was actually 'Cham P. Yun' instead of 'Victor',
  // you can use insertOne to modify the row identified by its primary key.
  await table.insertOne({
    matchId: 'match_0',
    round: 1,
    score: null,                // Set score to null to clear the previously inserted value
    winner: 'Cham P. Yun',
    mVector: [-0.6, 0.2, -0.7],
    });

  // The upserted row now has the following values:
  // { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

// insertMany examples

  // Inserts two rows in an unordered fashion.
  // Primary keys are required.
  // Unspecified columns are set to null.
  await table.insertMany([{
    matchId: 'fight4',
    round: 1,
    winner: 'Victor',
    score: 18,
    when: timestamp('2024-11-28T11:30:00Z'),
    fighters: new Set([
      uuid('0193539a-2770-8c09-a32a-111111111111'),
      uuid('019353e3-00b4-83f9-a127-222222222222'),
    ]),
    mVector: vector([0.4, -0.6, 0.2]),
    },
  // Insert with the primary key and 2 other values.
    {
    matchId: 'challenge6',
    round: 2,
    winner: 'Wynn Uhr',
    },
  ]);

  // Performs two inserts against the same row in an ordered fashion ('ordered: true').
  // Because inserts are also upserts in tables, if an ordered insert modifies the same row multiple times,
  // subsequent inserts overwrite prior inserts if the inserts modify the same columns.
  // In this example, the second insert overwrites the winner and mVector values from the first insert.
  //
  // In unordered inserts, upserts still occur, but the order is not guaranteed and the outcome is unpredictable.
  // However, unordered inserts are parallelized on the client and server.
  // They are generally more performant and recommended for most use cases.
  const res = await table.insertMany([
    {
      matchId: 'match_0',
      round: 1,                                       // All numbers are represented as JS numbers except varint and decimal
      score: 18,
      when: timestamp(),                              // Shorthand for new DataAPITimestamp(new Date())
      winner: 'Victor',
      fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
        uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
        uuid(7),                                      // Shorthand for UUID.v7()
      ]),
      mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for new DataAPIVector([0.2, -0.3, -0.5])
    },                                                // Use this instead of plain arrays to enable vector-specific optimizations
    {
      matchId: 'match_0',
      round: 1,
      score: null,                                   // Set score to null to insert no value or clear a previously-inserted value
      winner: 'Cham P. Yun',
      mVector: [-0.6, 0.2, -0.7],
    }],
    {
      timeout: 60000,
      ordered: true,
    });

  // Returns primary key of type { matchId: string, round: number }[]
  // Because both inserts have the same matchId, the primary key is 'match_0' for both
  const primaryKey = res.insertedIds;
  console.log(primaryKey[0].matchId, primaryKey[1].matchId);

  // After both inserts, the row has the following values:
  // { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

  const docs: TableSchema[] = Array.from({ length: 101 }, (_, i) => ({
    matchId: `match_${i}`,
    round: 1,
  }));
  await table.insertMany(docs);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();
// Inserts a single row
const res = await table.insertOne({
    matchId: 'match_0',
    round: 1,                                       // All non-varint/decimal numbers are represented as JS numbers
    score: 18,
    when: timestamp(),                              // Shorthand for new DataAPITimestamp(new Date())
    winner: 'Victor',
    fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
      uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
      uuid(4),                                      // Shorthand for UUID.v4()
    ]),
    mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for new DataAPIVector([0.2, -0.3, -0.5])
  });                                               // Use this instead of plain arrays to enable vector-specific optimizations

// Returns primary key of type { id: string, time: DataAPITimestamp }
const primaryKey = res.insertedId;
console.log(primaryKey.matchId);

// Inserts are also upserts in tables.
// If the winner of round 1 was actually 'Cham P. Yun' instead of 'Victor',
// you can use insertOne to modify the row identified by its primary key.
await table.insertOne({
  matchId: 'match_0',
  round: 1,
  score: null,                // Set score to null to clear the previously inserted value
  winner: 'Cham P. Yun',
  mVector: [-0.6, 0.2, -0.7],
  });

// The upserted row now has the following values:
// { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

For more information, see the Client reference.

Insert a row with a value for every column:

Table<Row> table = db.getTable("games");
table.insertOne(new Row()
  .addText("match_id", "match_0")
  .addInt("round", 1)
  .addVector("m_vector", new DataAPIVector(new float[]{0.4f, -0.6f, 0.2f}))
  .addInt("score", 18)
  .addTimeStamp("when", Instant.now())
  .addText("winner", "Victor")
  .addSet("fighters", Set
   .of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111"))));

Insert a row with some columns specified and unspecified columns set to null:

Table<Row> table = db.getTable("games");
table.insertOne(new Row()
  .addText("match_id", "match_0")
  .addInt("round", 1)
  .addText("winner", "Victor Vector")
  .addSet("fighters", Set
   .of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111"),
       UUID.fromString("0193539a-2880-8875-9f07-222222222222")
    )
  )
);

Parameters:

Name Type Summary

row

Row

Defines the row to insert. This object is similar to a Map where you can add the object you like with utilities methods. At minimum, you must specify the primary key values in full. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

options

TableInsertOneOptions

Specialization of the Table object overriding default configuration (DataAPIOptions)

Returns:

TableInsertOneResult: An instance presenting the primary key of the inserted row and also the schema of the primary key.

If any of the inserted columns are of the wrong datatype, or wrongly encoded, the entire insert will fail.

{
  "status": {
    "primaryKeySchema": {
      "match_id": {
        "type": "text"
      },
      "round": {
        "type": "int"
      }
    },
    "insertedIds": [
      [
        "match_1",
        2
      ]
    ]
  }
}

Example:

package com.datastax.astra.client.tables;

import com.datastax.astra.client.DataAPIClient;
import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.core.vector.DataAPIVector;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.commands.results.TableInsertOneResult;
import com.datastax.astra.client.tables.definition.columns.ColumnDefinition;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public class InsertRow {
  public static void main(String[] args) {
   Database db = new DataAPIClient("token").getDatabase("endpoint");
   Table<Row> table = db.getTable("games");
   TableInsertOneResult result = table.insertOne(new Row()
     .addText("match_id", "mtch_0")
     .addInt("round", 1)
     .addVector("m_vector", new DataAPIVector(new float[]{0.4f, -0.6f, 0.2f}))
     .addInt("score", 18)
     .addTimeStamp("when", Instant.now())
     .addText("winner", "Victor")
     .addSet("fighters", Set.of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111"))));

   List<Object> youPk = result.getInsertedId();
   Map<String, ColumnDefinition> yourPkSchema = result.getPrimaryKeySchema();

   // Leveraging object mapping
   Game match1 = new Game()
     .matchId("mtch_1")
     .round(2)
     .score(20)
     .when(Instant.now())
     .winner("Victor")
     .fighters(Set.of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111")))
     .vector(new DataAPIVector(new float[]{0.4f, -0.6f, 0.2f}));
   db.getTable("games", Game.class).insertOne(match1);
  }
}

To insert a row, define a document object containing key-value pairs of column names and values to insert. Primary key values are required. Any unspecified columns are set to null.

The following example inserts a row with scalar, map, list, and set data. The format of the values for each column depend on the column’s data type.

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE/ASTRA_DB_TABLE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "insertOne": {
    "document": {
      "string_column": "value",
      "int_column": 2,
      "boolean_column": true,
      "float_column": "NaN",
      "map_column": {
        "key1": "value1",
        "key2": "value2"
      },
      "list_column": [ 10, 11, 12 ],
      "set_column": [ 9, 8, 7 ]
    }
  }
}' | jq

You can insert pre-generated vector data into a vector column as an array or as a binary encoded value. Alternatively, if the column has a vectorize integration, you can automatically generate an embedding from a string.

# Insert vector data as an array
"vector_column": [ 0.1, -0.2, 0.3 ]

# Insert vector data with $binary
"vector_column": { "$binary": "PczMzb5MzM0+mZma" }

# Generate an embedding with vectorize
"vector_column": "Text to vectorize"

For more information, see Vector type.

Parameters:

Name Type Summary

insertOne

command

Data API command to insert one row in a table.

document

object

Defines the row to insert. Contains key-value pairs for each column in the table. At minimum, primary key values are required. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

Returns:

A successful response contains primaryKeySchema and insertedIds:

  • primaryKeySchema is an object that describes the table’s primary key definition, including column names and types.

  • insertedIds is a nested array containing the values inserted for each primary key column. If primaryKeySchema has multiple columns, then insertedIds contains the value for each column.

If any of the inserted columns are of the wrong datatype, or wrongly encoded, the entire insert will fail.

Example response for a single-column primary key
{
  "status": {
    "primaryKeySchema": {
      "email": {
        "type": "ascii"
      }
    },
    "insertedIds": [
      [
        "tal@example.com"
      ]
    ]
  }
}
Example response for a multi-column primary key
{
  "status": {
    "primaryKeySchema": {
      "email": {
        "type": "ascii"
      },
      "graduation_year": {
        "type": "int"
      }
    },
    "insertedIds": [
      [
        "tal@example.com",
        2014
      ]
    ]
  }
}

Example:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace/students" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "insertOne": {
    "document": {
      "name": "Tal Noor",
      "email": "tal@example.com",
      "graduated": true,
      "graduation_year": 2014,
      "grades": {
        "biology_101": 98,
        "math_202": 91
      },
      "extracurriculars": [ "Robotics club", "Cycling team" ],
      "semester_gpas": [ 3.9, 4.0, 3.7 ]
    }
  }
}' | jq

Insert rows

Insert new rows in a table.

If a row with the described primary key already exists in the table, the row will be overwritten with the specified column values. Unspecified columns will remain unchanged.

You can use this command to insert rows in existing CQL tables, but the Data API does not support all CQL data types or modifiers. For more information, see Column data types.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Insert many rows concurrently:

insert_result = my_table.insert_many(
    [
        {
            "match_id": "fight4",
            "round": 1,
            "winner": "Victor",
            "score": 18,
            "when": DataAPITimestamp.from_string(
                "2024-11-28T11:30:00Z",
            ),
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
                UUID('019353e3-00b4-83f9-a127-222222222222'),
            ]),
            "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        },
        {"match_id": "fight5", "round": 1, "winner": "Adam"},
        {"match_id": "fight5", "round": 2, "winner": "Betta"},
        {"match_id": "fight5", "round": 3, "winner": "Caio"},
        {
            "match_id": "challenge6",
            "round": 1,
            "winner": "Donna",
            "m_vector": [0.9, -0.1, -0.3],
        },
        {"match_id": "challenge6", "round": 2, "winner": "Erick"},
        {"match_id": "challenge6", "round": 3, "winner": "Fiona"},
        {"match_id": "tournamentA", "round": 1, "winner": "Gael"},
        {"match_id": "tournamentA", "round": 2, "winner": "Hanna"},
        {
            "match_id": "tournamentA",
            "round": 3,
            "winner": "Ian",
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
            ]),
        },
        {"match_id": "fight7", "round": 1, "winner": "Joy"},
        {"match_id": "fight7", "round": 2, "winner": "Kevin"},
        {"match_id": "fight7", "round": 3, "winner": "Lauretta"},
    ],
    concurrency=10,
    chunk_size=3,
)

The previous example has a very low chunk_size for demonstration purposes. For best performance, DataStax recommends using the default chunk_size.

Perform an ordered insertion:

my_table.insert_many(
    [
        {"match_id": "fight5", "round": 1, "winner": "Adam0"},
        {"match_id": "fight5", "round": 2, "winner": "Betta0"},
        {"match_id": "fight5", "round": 3, "winner": "Caio0"},
        {"match_id": "fight5", "round": 1, "winner": "Adam Zuul"},
        {"match_id": "fight5", "round": 2, "winner": "Betta Vigo"},
        {"match_id": "fight5", "round": 3, "winner": "Caio Gozer"},
    ],
    ordered=True,
)

When ordered=True, the operation stops if it encounters a row that can’t be inserted due to missing primary keys, incompatible values, or otherwise.

Parameters:

Name Type Summary

rows

Iterable[dict]

An iterable of dictionaries, each defining a row to insert. Each dictionary contains key-value pairs for each column in the table. At minimum, primary key values are required. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

ordered

bool

If False (default), insertions occur in an arbitrary order with possible concurrency. If True, insertions occur sequentially. If you don’t need ordered inserts, DataStax recommends False, which typically results in a much higher insert throughput than an equivalent ordered insertion.

concurrency

int | None

The maximum number of concurrent requests to the API at a given time. It cannot be more than one for ordered insertions.

chunk_size

int | None

The number of rows to insert in a single API request.

Leave it unspecified (recommended) to use the system default.

general_method_timeout_ms

int | None

a timeout, in milliseconds, to impose on the whole operation, which may consist of several API requests. If not provided, the corresponding Table defaults apply. This parameter is aliased as timeout_ms for convenience.

request_timeout_ms

int | None

a timeout, in milliseconds, to impose on each individual HTTP request to the Data API to accomplish the operation. If not provided, the corresponding Table defaults apply.

Returns:

TableInsertManyResult: An instance of TableInsertManyResult detailing the primary key of the inserted rows, both as dictionaries and ordered tuples.

Example response (reformatted for clarity)
TableInsertManyResult(
  inserted_ids=[
    {'match_id': 'fight4', 'round': 1},
    {'match_id': 'fight5', 'round': 1},
    {'match_id': 'fight5', 'round': 2},
    {'match_id': 'fight5', 'round': 3},
    {'match_id': 'challenge6', 'round': 1}
    ... (13 total)
  ],
  inserted_id_tuples=[
    ('fight4', 1), ('fight5', 1), ('fight5', 2),
    ('fight5', 3), ('challenge6', 1) ... (13 total)
  ],
  raw_results=...
)
Full example script
from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

from astrapy.constants import SortMode
from astrapy.info import (
    CreateTableDefinition,
    ColumnType,
)

my_table = database.create_table(
    "games",
    definition=(
        CreateTableDefinition.builder()
        .add_column("match_id", ColumnType.TEXT)
        .add_column("round", ColumnType.TINYINT)
        .add_vector_column("m_vector", dimension=3)
        .add_column("score", ColumnType.INT)
        .add_column("when", ColumnType.TIMESTAMP)
        .add_column("winner", ColumnType.TEXT)
        .add_set_column("fighters", ColumnType.UUID)
        .add_partition_by(["match_id"])
        .add_partition_sort({"round": SortMode.ASCENDING})
        .build()
    ),
)

# Insert complete and partial rows at once (concurrently)
from astrapy.data_types import (
    DataAPISet,
    DataAPITimestamp,
    DataAPIVector,
)
from astrapy.ids import UUID

insert_result = my_table.insert_many(
    [
        {
            "match_id": "fight4",
            "round": 1,
            "winner": "Victor",
            "score": 18,
            "when": DataAPITimestamp.from_string(
                "2024-11-28T11:30:00Z",
            ),
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
                UUID('019353e3-00b4-83f9-a127-222222222222'),
            ]),
            "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        },
        {"match_id": "fight5", "round": 1, "winner": "Adam"},
        {"match_id": "fight5", "round": 2, "winner": "Betta"},
        {"match_id": "fight5", "round": 3, "winner": "Caio"},
        {
            "match_id": "challenge6",
            "round": 1,
            "winner": "Donna",
            "m_vector": [0.9, -0.1, -0.3],
        },
        {"match_id": "challenge6", "round": 2, "winner": "Erick"},
        {"match_id": "challenge6", "round": 3, "winner": "Fiona"},
        {"match_id": "tournamentA", "round": 1, "winner": "Gael"},
        {"match_id": "tournamentA", "round": 2, "winner": "Hanna"},
        {
            "match_id": "tournamentA",
            "round": 3,
            "winner": "Ian",
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
            ]),
        },
        {"match_id": "fight7", "round": 1, "winner": "Joy"},
        {"match_id": "fight7", "round": 2, "winner": "Kevin"},
        {"match_id": "fight7", "round": 3, "winner": "Lauretta"},
    ],
    concurrency=10,
    chunk_size=3,
)
insert_result.inserted_ids
# [{'match_id': 'fight4', 'round': 1}, {'match_id': 'fight5', ...
insert_result.inserted_id_tuples
# [('fight4', 1), ('fight5', 1), ('fight5', 2), ('fight5', 3), ...

# Ordered insertion
# (would stop on first failure; predictable end result on the database)
my_table.insert_many(
    [
        {"match_id": "fight5", "round": 1, "winner": "Adam0"},
        {"match_id": "fight5", "round": 2, "winner": "Betta0"},
        {"match_id": "fight5", "round": 3, "winner": "Caio0"},
        {"match_id": "fight5", "round": 1, "winner": "Adam Zuul"},
        {"match_id": "fight5", "round": 2, "winner": "Betta Vigo"},
        {"match_id": "fight5", "round": 3, "winner": "Caio Gozer"},
    ],
    ordered=True,
)
# TableInsertManyResult(inserted_ids=[{'match_id': 'fight5', 'round': 1}, ...

Example:

# Insert complete and partial rows at once (concurrently)
from astrapy.data_types import (
    DataAPISet,
    DataAPITimestamp,
    DataAPIVector,
)
from astrapy.ids import UUID

insert_result = my_table.insert_many(
    [
        {
            "match_id": "fight4",
            "round": 1,
            "winner": "Victor",
            "score": 18,
            "when": DataAPITimestamp.from_string(
                "2024-11-28T11:30:00Z",
            ),
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
                UUID('019353e3-00b4-83f9-a127-222222222222'),
            ]),
            "m_vector": DataAPIVector([0.4, -0.6, 0.2]),
        },
        {"match_id": "fight5", "round": 1, "winner": "Adam"},
        {"match_id": "fight5", "round": 2, "winner": "Betta"},
        {"match_id": "fight5", "round": 3, "winner": "Caio"},
        {
            "match_id": "challenge6",
            "round": 1,
            "winner": "Donna",
            "m_vector": [0.9, -0.1, -0.3],
        },
        {"match_id": "challenge6", "round": 2, "winner": "Erick"},
        {"match_id": "challenge6", "round": 3, "winner": "Fiona"},
        {"match_id": "tournamentA", "round": 1, "winner": "Gael"},
        {"match_id": "tournamentA", "round": 2, "winner": "Hanna"},
        {
            "match_id": "tournamentA",
            "round": 3,
            "winner": "Ian",
            "fighters": DataAPISet([
                UUID("0193539a-2770-8c09-a32a-111111111111"),
            ]),
        },
        {"match_id": "fight7", "round": 1, "winner": "Joy"},
        {"match_id": "fight7", "round": 2, "winner": "Kevin"},
        {"match_id": "fight7", "round": 3, "winner": "Lauretta"},
    ],
    concurrency=10,
    chunk_size=3,
)
insert_result.inserted_ids
# [{'match_id': 'fight4', 'round': 1}, {'match_id': 'fight5', ...
insert_result.inserted_id_tuples
# [('fight4', 1), ('fight5', 1), ('fight5', 2), ('fight5', 3), ...

# Ordered insertion
# (would stop on first failure; predictable end result on the database)
my_table.insert_many(
    [
        {"match_id": "fight5", "round": 1, "winner": "Adam0"},
        {"match_id": "fight5", "round": 2, "winner": "Betta0"},
        {"match_id": "fight5", "round": 3, "winner": "Caio0"},
        {"match_id": "fight5", "round": 1, "winner": "Adam Zuul"},
        {"match_id": "fight5", "round": 2, "winner": "Betta Vigo"},
        {"match_id": "fight5", "round": 3, "winner": "Caio Gozer"},
    ],
    ordered=True,
)
# TableInsertManyResult(inserted_ids=[{'match_id': 'fight5', 'round': 1}, ...

For more information, see the Client reference.

Basic unordered insert:

const docs = Array.from({ length: 50 }, (_, i) => ({ matchId: `match${i}`, round: 0 }));
await table.insertMany(docs);

Basic ordered insert:

const docs = Array.from({ length: 50 }, (_, i) => ({ matchId: `match${i}`, round: 0 }));
await table.insertMany(docs, { ordered: true });

Parameters:

Name Type Summary

rows

Schema[]

An array of object expressing the rows to insert. Each object contains key-value pairs for each column in the table. At minimum, primary key values are required. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

options?

TableInsertManyOptions

The options for this operation.

Options (TableInsertManyOptions):

Name Type Summary

ordered?

boolean

If false (default), insertions occur in an arbitrary order with possible concurrency. If true, insertions occur sequentially. If you don’t need ordered inserts, DataStax recommends false, which typically results in a much higher insert throughput than an equivalent ordered insertion.

concurrency?

number

The maximum number of concurrent requests to the API at a given time. Defaults to 8.

This is not available for ordered insertions.

chunkSize?

number

The number of rows to insert in a single API request.

Leave it unspecified (recommended) to use the system default.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Returns:

Promise<TableInsertManyResult<PKey>>: An object detailing the primary keys of the inserted rows, typed as inferred from the PKey of the table’s type, or Partial<RSchema> if it cannot be inferred.

If there is a failure and the request is ordered, the operation stop at the first failure and throw a TableInsertManyError. If the chunkSize is greater than one, the entire chunk containing the failing row will fail to insert.

If there is a failure and the request is unordered, the operation will try to process the remaining rows and then throw a TableInsertManyError.

TableInsertManyError will indicate which rows were successfully inserted.

Example response
{
  insertedIds: [
    { matchId: 'match0', round: 0 },
    { matchId: 'match1', round: 0 },
    { matchId: 'match2', round: 0 },
    // ...
  ],
  insertedCount: 50,
}

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema, timestamp, uuid, vector } from '@datastax/astra-db-ts';

// Instantiate the client and connect to the database
const client = new DataAPIClient();
const db = client.db(process.env.CLIENT_DB_URL!, { token: process.env.CLIENT_DB_TOKEN! });

// Create table schema using bespoke Data API table definition syntax, and then infer the type.
// For information about table typing and definitions, see the documentation for createTable.
const TableDefinition = <const>{
  columns: {
    matchId: 'text'
    round: 'tinyint',
    mVector: { type: 'vector', dimension: 3 },
    score: 'int',
    when: 'timestamp',
    winner: 'text',
    fighters: { type: 'set', valueType: 'uuid' },
  },
  primaryKey: {
    partitionBy: ['matchId'],
    partitionSort: { round: 1 },
  },
} satisfies CreateTableDefinition;

type TableSchema = InferTableSchema<typeof TableDefinition>;
type TablePK = InferTablePrimaryKey<typeof TableDefinition>;

(async function () {
  // Create a table with the given TableSchema type if a 'games' table doesn't already exist
  const table = await db.createTable<TableSchema, TablePK>('games', { definition: TableDefinition, ifNotExists: true });

// Use insertOne and insertMany to insert rows into tables.
// Inserts are also upserts for tables.

// insertOne examples

  // Inserts a single row
  const res = await table.insertOne({
      matchId: 'match_0',
      round: 1,                                       // All non-varint/decimal numbers are represented as JS numbers
      score: 18,
      when: timestamp(),                              // Shorthand for `new DataAPITimestamp(new Date())`
      winner: 'Victor',
      fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
        uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
        uuid(4),                                      // Shorthand for `UUID.v4()`
      ]),
      mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for `new DataAPIVector([0.2, -0.3, -0.5])`
    });                                               // Use this instead of plain arrays to enable vector-specific optimizations

  // Returns primary key of type { id: string, time: DataAPITimestamp }
  const primaryKey = res.insertedId;
  console.log(primaryKey.matchId);

  // Inserts are also upserts in tables.
  // If the winner of round 1 was actually 'Cham P. Yun' instead of 'Victor',
  // you can use insertOne to modify the row identified by its primary key.
  await table.insertOne({
    matchId: 'match_0',
    round: 1,
    score: null,                // Set `score` to `null` to clear the previously inserted value
    winner: 'Cham P. Yun',
    mVector: [-0.6, 0.2, -0.7],
    });

  // The upserted row now has the following values:
  // { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

// insertMany examples

  // Inserts two rows in an unordered fashion.
  // Primary keys are required.
  // Unspecified columns are set to null.
  await table.insertMany([{
    matchId: 'fight4',
    round: 1,
    winner: 'Victor',
    score: 18,
    when: timestamp('2024-11-28T11:30:00Z'),
    fighters: new Set([
      uuid('0193539a-2770-8c09-a32a-111111111111'),
      uuid('019353e3-00b4-83f9-a127-222222222222'),
    ]),
    mVector: vector([0.4, -0.6, 0.2]),
    },
  // Insert with the primary key and 2 other values.
    {
    matchId: 'challenge6',
    round: 2,
    winner: 'Wynn Uhr',
    },
  ]);

  // Performs two inserts against the same row in an ordered fashion ('ordered: true').
  // Because inserts are also upserts in tables, if an ordered insert modifies the same row multiple times,
  // subsequent inserts overwrite prior inserts if the inserts modify the same columns.
  // In this example, the second insert overwrites the `winner` and `mVector` values from the first insert.
  //
  // In unordered inserts, upserts still occur, but the order is not guaranteed and the outcome is unpredictable.
  // However, unordered inserts are parallelized on the client and server.
  // They are generally more performant and recommended for most use cases.
  const res = await table.insertMany([
    {
      matchId: 'match_0',
      round: 1,                                       // All numbers are represented as JS numbers except varint and decimal
      score: 18,
      when: timestamp(),                              // Shorthand for `new DataAPITimestamp(new Date())`
      winner: 'Victor',
      fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
        uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
        uuid(7),                                      // Shorthand for `UUID.v7()`
      ]),
      mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for `new DataAPIVector([0.2, -0.3, -0.5])`
    },                                                // Use this instead of plain arrays to enable vector-specific optimizations
    {
      matchId: 'match_0',
      round: 1,
      score: null,                                   // Set `score` to `null` to insert no value or clear a previously-inserted value
      winner: 'Cham P. Yun',
      mVector: [-0.6, 0.2, -0.7],
    }],
    {
      timeout: 60000,
      ordered: true,
    });

  // Returns primary key of type { matchId: string, round: number }[]
  // Because both inserts have the same matchId, the primary key is 'match_0' for both
  const primaryKey = res.insertedIds;
  console.log(primaryKey[0].matchId, primaryKey[1].matchId);

  // After both inserts, the row has the following values:
  // { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

  const docs: TableSchema[] = Array.from({ length: 101 }, (\_, i) => ({
    matchId: \`match_${i}`,
    round: 1,
  }));
  await table.insertMany(docs);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();
// Inserts two rows in an unordered fashion.
// Primary keys are required.
// Unspecified columns are set to null.
await table.insertMany([{
  matchId: 'fight4',
  round: 1,
  winner: 'Victor',
  score: 18,
  when: timestamp('2024-11-28T11:30:00Z'),
  fighters: new Set([
    uuid('0193539a-2770-8c09-a32a-111111111111'),
    uuid('019353e3-00b4-83f9-a127-222222222222'),
  ]),
  mVector: vector([0.4, -0.6, 0.2]),
  },
// Insert with the primary key and 2 other values.
  {
  matchId: 'challenge6',
  round: 2,
  winner: 'Wynn Uhr',
  },
]);

// Performs two inserts against the same row in an ordered fashion ('ordered: true').
// Because inserts are also upserts in tables, if an ordered insert modifies the same row multiple times,
// subsequent inserts overwrite prior inserts if the inserts modify the same columns.
// In this example, the second insert overwrites the `winner` and `mVector` values from the first insert.
//
// In unordered inserts, upserts still occur, but the order is not guaranteed and the outcome is unpredictable.
// However, unordered inserts are parallelized on the client and server.
// They are generally more performant and recommended for most use cases.
const res = await table.insertMany([
  {
    matchId: 'match_0',
    round: 1,                                       // All numbers are represented as JS numbers except varint and decimal
    score: 18,
    when: timestamp(),                              // Shorthand for `new DataAPITimestamp(new Date())`
    winner: 'Victor',
    fighters: new Set([                             // Use native Maps, Sets, and Arrays for maps, sets, and lists.
      uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in maps, sets, and lists.
      uuid(7),                                      // Shorthand for `UUID.v7()`
    ]),
    mVector: vector([0.2, -0.3, -0.5]),             // Shorthand for `new DataAPIVector([0.2, -0.3, -0.5])`
  },                                                // Use this instead of plain arrays to enable vector-specific optimizations
  {
    matchId: 'match_0',
    round: 1,
    score: null,                                   // Set `score` to `null` to insert no value or clear a previously-inserted value
    winner: 'Cham P. Yun',
    mVector: [-0.6, 0.2, -0.7],
  }],
  {
    timeout: 60000,
    ordered: true,
  });

// Returns primary key of type { matchId: string, round: number }[]
// Because both inserts have the same matchId, the primary key is 'match_0' for both
const primaryKey = res.insertedIds;
console.log(primaryKey[0].matchId, primaryKey[1].matchId);

// After both inserts, the row has the following values:
// { matchId: 'match_0', round: 1, score: null, when: <timestamp>, winner: 'Cham P. Yun', fighters: <uuid[]>, mVector: [-0.6, 0.2, -0.7] }

const docs: TableSchema[] = Array.from({ length: 101 }, (\_, i) => ({
  matchId: \`match_${i}`,
  round: 1,
}));
await table.insertMany(docs);

For more information, see the Client reference.

Insert many rows concurrently:

Table<Row> table = db.getTable("games");

TableInsertManyOptions options = new TableInsertManyOptions()
  .concurrency(10)
  .ordered(false)
  .chunkSize(3);

List<Row> myRows = new ArrayList<>();
myRows.add(new Row().addText("match_id", "fight4")
  .addInt("round", 1)
  .addText("winner", "Victor")
  .addInt("score", 18)
  .addTimeStamp("when", Instant.now())
  .addSet("fighters", Set.of(
    UUID.fromString("0193539a-2770-8c09-a32a-111111111111"),
    UUID.fromString("019353e3-00b4-83f9-a127-222222222222")
    )
   )
  .addVector("m_vector", new DataAPIVector(new float[]{0.4f, -0.6f, 0.2f})));
myRows.add(new Row().addText("match_id", "fight5").addInt("round", 1).addText("winner", "Adam"));
myRows.add(new Row().addText("match_id", "fight5").addInt("round", 2).addText("winner", "Betta"));
myRows.add(new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio"));
myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 1).addText("winner", "Donna")
 .addVector("m_vector", new DataAPIVector(new float[]{0.9f, -0.1f, -0.3f})));
myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 2).addText("winner", "Erick"));
myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 3).addText("winner", "Fiona"));
myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 1).addText("winner", "Gael"));
myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 2).addText("winner", "Hanna"));
myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 3).addText("winner", "Ian")
 .addSet("fighters", Set.of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111"))));
myRows.add(new Row().addText("match_id", "fight7").addInt("round", 1).addText("winner", "Joy"));
myRows.add(new Row().addText("match_id", "fight7").addInt("round", 2).addText("winner", "Kevin"));
myRows.add(new Row().addText("match_id", "fight7").addInt("round", 3).addText("winner", "Lauretta"));
TableInsertManyResult insertResults = table
  .insertMany(myRows, options);

The previous example has a very low chunk_size for demonstration purposes. For best performance, DataStax recommends using the default chunk_size.

Perform an ordered insertion:

TableInsertManyResult results2 = table.insertMany(
 List.of(
  new Row().addText("match_id", "fight5").addInt("round", 1).addText("winner", "Adam0"),
  new Row().addText("match_id", "fight5").addInt("round", 2).addText("winner", "Betta0"),
  new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio0"),
  new Row().addText("match_id", "fight5").addInt("round", 1).addText("winner", "Adam Zuul"),
  new Row().addText("match_id", "fight5").addInt("round", 2).addText("winner", "Betta Vigo"),
  new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio Gozer")
 ),
 new TableInsertManyOptions()
  .ordered(true));

If ordered(true), the operation stops if it encounters a row that can’t be inserted due to missing primary keys, incompatible data, or otherwise.

Parameters:

Name Type Summary

rows

List<Row>

The list of Rows to insert.

At minimum, you must specify the primary key values in full for each row. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and each column’s type. For more information, see Create a table and Column data types.

options

TableInsertManyOptions

Configuration and specialization of the Options

Name Type Summary

ordered

bool

If False (default), insertions occur in an arbitrary order with possible concurrency. If True, insertions occur sequentially. If you don’t need ordered inserts, DataStax recommends False, which typically results in a much higher insert throughput than an equivalent ordered insertion.

concurrency

int

The maximum number of concurrent requests to the API at a given time. It cannot be more than one for ordered insertions.

chunkSize

int

The number of rows to insert in a single API request.

Leave it unspecified (recommended) to use the system default.

Returns:

TableInsertManyResult: An instance of TableInsertManyResult detailing the primary key of the inserted rows and the schema of the primary key.

{
  "status": {
    "primaryKeySchema": {
      "match_id": {
        "type": "text"
      },
      "round": {
        "type": "int"
      }
    },
    "insertedIds": [
      ["fight4",1 ],
      ["fight5",1],
      ["fight5",2]
    ]
  }
}

Example:

package com.datastax.astra.client.tables;

import com.datastax.astra.client.DataAPIClient;
import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.DataAPIDestination;
import com.datastax.astra.client.core.auth.UsernamePasswordTokenProvider;
import com.datastax.astra.client.core.options.DataAPIClientOptions;
import com.datastax.astra.client.core.vector.DataAPIVector;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.databases.DatabaseOptions;
import com.datastax.astra.client.tables.commands.options.TableInsertManyOptions;
import com.datastax.astra.client.tables.commands.results.TableInsertManyResult;
import com.datastax.astra.client.tables.commands.results.TableInsertOneResult;
import com.datastax.astra.client.tables.definition.columns.ColumnDefinition;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public class InsertManyRows {
  public static void main(String[] args) {
   Database db = new DataAPIClient("token").getDatabase("endpoint");

   Table<Row> table = db.getTable("games");

   TableInsertManyOptions options = new TableInsertManyOptions()
     .concurrency(10)
     .ordered(false)
     .chunkSize(3);

   List<Row> myRows = new ArrayList<>();
   myRows.add(new Row().addText("match_id", "fight4")
    .addInt("round", 1)
    .addText("winner", "Victor")
    .addInt("score", 18)
    .addTimeStamp("when", Instant.now())
    .addSet("fighters", Set.of(
     UUID.fromString("0193539a-2770-8c09-a32a-111111111111"),
     UUID.fromString("019353e3-00b4-83f9-a127-222222222222")))
    .addVector("m_vector",
        new DataAPIVector(new float[]{0.4f, -0.6f, 0.2f})));

  myRows.add(new Row()
   .addText("match_id", "fight5")
   .addInt("round", 1)
   .addText("winner", "Adam"));
  myRows.add(new Row()
   .addText("match_id", "fight5")
   .addInt("round", 2)
   .addText("winner", "Betta"));
  myRows.add(new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio"));
  myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 1).addText("winner", "Donna")
              .addVector("m_vector", new DataAPIVector(new float[]{0.9f, -0.1f, -0.3f})));
      myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 2).addText("winner", "Erick"));
      myRows.add(new Row().addText("match_id", "challenge6").addInt("round", 3).addText("winner", "Fiona"));
      myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 1).addText("winner", "Gael"));
      myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 2).addText("winner", "Hanna"));
      myRows.add(new Row().addText("match_id", "tournamentA").addInt("round", 3).addText("winner", "Ian")
              .addSet("fighters", Set.of(UUID.fromString("0193539a-2770-8c09-a32a-111111111111"))));
      myRows.add(new Row().addText("match_id", "fight7").addInt("round", 1).addText("winner", "Joy"));
      myRows.add(new Row().addText("match_id", "fight7").addInt("round", 2).addText("winner", "Kevin"));
      myRows.add(new Row().addText("match_id", "fight7").addInt("round", 3).addText("winner", "Lauretta"));
   TableInsertManyResult results = table.insertMany(myRows, options);

   TableInsertManyResult results2 = table.insertMany(
     List.of(
       new Row().addText("match_id", "fight5").addInt("round", 1).addText("winner", "Adam0"),
       new Row().addText("match_id", "fight5").addInt("round", 2).addText("winner", "Betta0"),
       new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio0"),
       new Row().addText("match_id", "fight5").addInt("round", 1).addText("winner", "Adam Zuul"),
       new Row().addText("match_id", "fight5").addInt("round", 2).addText("winner", "Betta Vigo"),
       new Row().addText("match_id", "fight5").addInt("round", 3).addText("winner", "Caio Gozer")),
   new TableInsertManyOptions().ordered(true));
  }
}

To insert multiple rows, provide a documents array containing an object for each row that you want to insert. Each row object contains key-value pairs of column names and values to insert. Primary key values are required. Any unspecified columns are set to null.

The following example inserts rows with scalar, map, list, and set data. The format of the values for each column depend on the column’s data type.

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE/ASTRA_DB_TABLE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "insertMany": {
    "documents": [
      {
        "string_key": "value1",
        "int_key": 2,
        "boolean_key": true,
        "float_column": -3.47
        "map_column": {
          "key1": "value1",
          "key2": "value2"
        },
      },
      {
        "string_key": "value2",
        "int_key": 7,
        "boolean_key": false,
        "list_column": [ 10, 11, 12 ],
      },
      {
        "string_key": "value3",
        "int_key": 9,
        "boolean_key": false,
        "set_column": [ 9, 8, 7 ]
      }
    ]
    "options": {
      "ordered": false,
      "returnDocumentPositions": true
    }
  }
}' | jq

You can insert pre-generated vector data into a vector column as an array or as a binary encoded value. Alternatively, if the column has a vectorize integration, you can automatically generate an embedding from a string.

# Insert vector data as an array
"vector_column": [ 0.1, -0.2, 0.3 ]

# Insert vector data with $binary
"vector_column": { "$binary": "PczMzb5MzM0+mZma" }

# Generate an embedding with vectorize
"vector_column": "Text to vectorize"

For more information, see Vector type.

Parameters:

Name Type Summary

insertMany

command

Data API command to insert multiples row in a table.

documents

array

An array of objects where each object represents a row to insert. Each row object contains key-value pairs for the columns in the table. At minimum, each row must include primary key values. Any unspecified columns are set to null.

The table definition determines the available columns, the primary key, and the column types. For more information, see Create a table and Column data types.

You can insert up to 100 rows per HTTP request. If you want to insert more rows at once, you must make multiple requests or use the Data API clients.

options

object

Options for the command, including ordered and returnDocumentPositions.

options.ordered

boolean

If false (default), insertions occur in an arbitrary order with possible concurrency. If true, insertions occur sequentially. If you don’t need ordered inserts, DataStax recommends false, which typically results in a much higher insert throughput than an equivalent ordered insertion.

options.returnDocumentPositions

boolean

If true, the response includes a status for each insertion. The default is false.

Returns:

A well-formed request returns a status object that contains primaryKeySchema and either insertedIds or documentResponses:

  • primaryKeySchema is an object that describes the table’s primary key definition, including column names and types.

  • insertedIds is returned if returnDocumentPositions was false or omitted in the request. It is a nested array containing the primary key values for each inserted row.

    If primaryKeySchema has multiple columns, then each insertedIds array contains the value for each column in the order specified in the primaryKeySchema.

  • documentResponses is returned if the request included "returnDocumentPositions": true. It is an array of objects where each object represents a row. Each object contains a status key describing the outcome of the insertion and an _id array that contains the primary key values for the row.

Carefully check the entire Data API response for errors to verify that all rows inserted successfully.

If there is an error in any row in the request, the outcome depends on the ordered parameter:

  • If "ordered": true, then all rows prior to the first errored row are inserted. The first errored row and all subsequent rows are skipped, and the Data API returns an error about the errored row.

  • If "ordered": false, then all well-formed rows are inserted, and the errored rows are skipped.

    For partially successful requests, the Data API returns a status object that describes successful insertions and an errors array that describes problems with rows that could not be inserted.

Example response for a single-column primary key
{
  "status": {
    "primaryKeySchema": {
      "email": {
        "type": "ascii"
      }
    },
    "insertedIds": [
      [
        "tal@example.com"
      ],
      [
        "sami@example.com"
      ],
      [
        "kirin@example.com"
      ]
    ]
  }
}
Example response for a multi-column primary key
{
  "status": {
    "primaryKeySchema": {
      "email": {
        "type": "ascii"
      },
      "graduation_year": {
        "type": "int"
      }
    },
    "insertedIds": [
      [
        "tal@example.com",
        2024
      ],
      [
        "sami@example.com",
        2024
      ],
      [
        "kiran@example.com",
        2024
      ]
    ]
  }
}

Example:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace/students" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "insertMany": {
    "documents": [
      {
        "name": "Tal Noor",
        "email": "tal@example.com",
        "graduated": true,
        "graduation_year": 2014,
        "grades": {
          "bio_101": 98,
          "math_202": 91
        },
        "extracurriculars": [ "Robotics club", "Cycling team" ],
        "semester_gpas": [ 3.9, 4.0, 3.7, 3.8 ]
      },
      {
        "name": "Sami Minh",
        "email": "sami@example.com",
        "graduated": true,
        "graduation_year": 2024,
        "grades": {
          "econ_101": 98,
          "econ_202": 91
        },
        "extracurriculars": [ "Debate team", "IM soccer" ],
        "semester_gpas": [ 3.6, 3.2, 3.7, 3.9 ]
      },
      {
        "name": "Kiran Jay",
        "email": "kiran@example.com",
        "graduated": true,
        "graduation_year": 2024,
        "grades": {
          "draw_101": 98,
          "pottery_301": 91
        },
        "extracurriculars": [ "RA", "Gardening club" ],
        "semester_gpas": [ 3.4, 3.6, 3.8, 3.7 ]
      }
    ]
  }
}' | jq

Was this helpful?

Give Feedback

How can we improve the documentation?

© 2024 DataStax | Privacy policy | Terms of use

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: +1 (650) 389-6000, info@datastax.com