Work with tables

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.

You can use the Data API to create, read, write, and drop tables containing structured data in Serverless (Vector) databases.

Tables are best for use cases where your data is structured and adheres to a pre-defined schema, known as a fixed schema. The database enforces schema compliance when you add or update data.

Whereas collections automatically index all fields, tables don’t have comprehensive automatic indexing. To optimize query performance, you must manually create and manage indexes for your table data. For more information about the role of indexes in tables, see Work with table indexes.

If your data doesn’t have a consistent, enforceable structure or you don’t want to manually manage indexes, consider using dynamic schema collections instead.

In Astra DB, tables reside inside keyspaces in databases. For information about managing databases and keyspaces programmatically, see Databases reference.

With the Data API clients, you use the Database class to manage tables themselves. Then, you use the Table class to work with table data.

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.

Work with existing CQL tables

For information about working with existing CQL tables through the Data API, including the CQL commands and types that the Data API supports, see Migrate from CQL.

Create a table

Create a new table in a keyspace in a Serverless (Vector) database.

When you create a table, you specify the following:

  • Table name

  • Column names and data types

  • Primary key, which is the unique identifier for the rows in the table

  • Additional table, command, or client-specific settings, which can be optional

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Create a table using a fluent interface for its definition:

table_definition = (
    CreateTableDefinition.builder()
    .add_column("match_id", ColumnType.TEXT)
    .add_column("round", ColumnType.INT)
    .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()
)
my_table = database.create_table(
    "games",
    definition=table_definition,
)

Use if_not_exists to call create_table without throwing an error if a table with the given name already exists. In which case, the request silently does nothing.

table_definition = ...  # (omitted)
my_table = database.create_table(
    "games",
    definition=table_definition,
    if_not_exists=True,
)

Parameters:

Name Type Summary

name

str

The name of the table.

definition

CreateTableDefinition | dict

A complete table definition for the table, including the column names, data types, other column settings, and the primary key.

This can be an instance of CreateTableDefinition or an equivalent nested dictionary, in which case it is parsed into a CreateTableDefinition. For examples of both formats, see the Example for this command.

Some types require specific column definitions, particularly maps, lists, sets, and vector columns. For more information about all types, see Column data types.

row_type

type

This parameter acts a formal specifier for the type checker. If omitted, the resulting Table is implicitly a Table[dict]. If provided, row_type must match the type hint specified in the assignment. For more information, see the Example for this command and Typing support.

keyspace

str | None

The keyspace where the table is to be created. If not specified, the general keyspace setting for the database is used.

if_not_exists

bool | None

If True, the command doesn’t throw an error if a table with the given name already exists. In this case, the command silently does nothing and no actual table creation takes place on the database.

If False (default), an error occurs if a table with the specified name already exists in the database.

if_not_exists: True, does not check the definition of any existing tables. This parameter checks table names only.

This means that the command succeeds if the given table name is already in use, even if the table definition is different.

table_admin_timeout_ms

int | None

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.

embedding_api_key

str | EmbeddingHeadersProvider

Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

As an alternative to Astra DB KMS authentication, use embedding_api_key to store one or more embedding provider API keys on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header (EmbeddingAPIKeyHeaderProvider) with operations that use vectorize.

Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

spawn_api_options

APIOptions

A complete or partial specification of the APIOptions to override the defaults inherited from the Database. This allows for nuanced table configuration. For example, if APIOptions is passed together with named timeout parameters, the latter take precedence in their respective settings.

Returns:

Table - A Table object that is typed as Table[dict] by default. To provide a more specific type hint, you must pass a row_type parameter matching the appropriate type hint for the variable used in the assignment. For more information, see the Example for this command and Typing support.

Example response (reformatted for clarity)
Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

# Create a table using the fluent syntax for definition:
from astrapy.constants import SortMode
from astrapy.info import (
    CreateTableDefinition,
    ColumnType,
)
table_definition = (
    CreateTableDefinition.builder()
    .add_column("match_id", ColumnType.TEXT)
    .add_column("round", ColumnType.INT)
    .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()
)
my_table = database.create_table(
    "games",
    definition=table_definition,
)

# Create a table with the definition as object:
# (and do not raise an error if the table exists already)
from astrapy.info import (
    CreateTableDefinition,
    TablePrimaryKeyDescriptor,
    TableScalarColumnTypeDescriptor,
    TableValuedColumnType,
    TableValuedColumnTypeDescriptor,
    TableVectorColumnTypeDescriptor,
)
table_definition_1 = CreateTableDefinition(
    columns={
        "match_id": TableScalarColumnTypeDescriptor(
            ColumnType.TEXT,
        ),
        "round": TableScalarColumnTypeDescriptor(
            ColumnType.INT,
        ),
        "m_vector": TableVectorColumnTypeDescriptor(
            column_type="vector", dimension=3
        ),
        "score": TableScalarColumnTypeDescriptor(
            ColumnType.INT,
        ),
        "when": TableScalarColumnTypeDescriptor(
            ColumnType.TIMESTAMP,
        ),
        "winner": TableScalarColumnTypeDescriptor(
            ColumnType.TEXT,
        ),
        "fighters": TableValuedColumnTypeDescriptor(
            column_type=TableValuedColumnType.SET,
            value_type=ColumnType.UUID,
        ),
    },
    primary_key=TablePrimaryKeyDescriptor(
        partition_by=["match_id"],
        partition_sort={"round": SortMode.ASCENDING},
    ),
)
my_table_1 = database.create_table(
    "games",
    definition=table_definition_1,
    if_not_exists=True,
)

# Create a table with the definition as plain dictionary:
# (and do not raise an error if the table exists already)
table_definition_2 = {
    "columns": {
        "match_id": {"type": "text"},
        "round": {"type": "int"},
        "m_vector": {"type": "vector", "dimension": 3},
        "score": {"type": "int"},
        "when": {"type": "timestamp"},
        "winner": {"type": "text"},
        "fighters": {"type": "set", "valueType": "uuid"},
    },
    "primaryKey": {
        "partitionBy": ["match_id"],
        "partitionSort": {"round": 1},
    },
}
my_table_2 = database.create_table(
    "games",
    definition=table_definition_2,
    if_not_exists=True,
)

For more information, see the Client reference.

The TypeScript client provides multiple ways to create create tables, depending on your typing preferences and ser/des configuration (if modified). The following strategies and examples focus on typing your tables. For details about other parameters, such as table definitions, see the Parameters and Example for this command.

  • Automatic type inference

  • Manually typed tables

  • Untyped tables

Like Zod or arktype, the Data API TypeScript client can automatically infer the type of the table’s schema.

By default, the client infers TS-equivalent type of the table’s schema from the definition object that you provide. There are several ways to extract this type to reuse within your application.

Infer from definition object

To infer the type from the definition object, you must specify the definition with a <const> assertion so that TypeScript can infer the exact unwidened type of the object.

Additionally, DataStax strongly recommends using satisfies CreateTableDefinition for typechecking purposes.

import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema } from '@datastax/astra-db-ts';

// Instantiate the client and connect to the database
const client = new DataAPIClient();
const db = client.db('ENDPOINT', { token: 'TOKEN' });

// Create table schema using bespoke Data API table definition syntax
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;

// Infer the TS-equivalent type from the table definition. Equivalent to:
//
// interface TableSchema {
//   matchId: string,                // Primary key components are not nullable
//   round: number,
//   score?: number | null,          // Non-primary key columns are optional and can return as null
//   winner?: string | null,
//   when?: DataAPITimestamp | null,
//   fighters?: Set<UUID>,           // Maps, lists, and sets are optional to insert, but returns as empty instead of null
//   mVector?: DataAPIVector | null, // Vectors can be null.
// }
//
// The preceding definition uses some custom types, like DataAPITimestamp, UUID, and DataAPIVector.
// If necessary, you can modify the ser/des logic to use different datatypes instead.
// However, you must provide your own types in that case.
// For more information, see the Typescript client usage documentation.
type TableSchema = InferTableSchema<typeof TableDefinition>;

// Infer the TS-equivalent type of the primary key from the table definition. Equivalent to:
// type TablePK = Pick<TableSchema, 'matchId' | 'round'>;
type TablePK = InferTablePrimaryKey<typeof TableDefinition>;

// Main function
(async function bootstrap() {
  // Provide the type explicitly, so TypeScript doesn't have to run any additional typechecking, just to get the same result
  const table = await db.createTable<TableSchema, TablePK>('games', { definition: TableDefinition });

  // You can then use TableSchema as you would any other type.
  // @ts-expect-error - 'badfield' is not a valid column as per the table's type
  const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

  // res.insertedId :: { matchId: string, round: number }
  const res = await table.insertOne(row);
})();
Infer from created table

For this strategy, you must write the table definition inline or create it with a <const> assertion. For an example of <const>, see Infer from definition object.

import { DataAPIClient, InferTablePrimaryKey, InferTableSchema } from '@datastax/astra-db-ts';

// Instantiate the client and connect to the database
const client = new DataAPIClient();
const db = client.db('ENDPOINT', { token: 'TOKEN' });

// You must put createTable in its own function with no explicit return type annotation.
// This ensures that the type of the table is available from the top-level scope.
//
// If the environment doesn't allow top-level awaits, then you can't call createTable from the top level
// (without creating an unawaited promise) to then extract the type from.
//
// Therefore, you must extract the type from the function itself, and then the function called.
async function mkGamesTable() {
  return await db.createTable('games', {
    definition: {
      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 },
      },
    }
  });
}

// Infer the TS-equivalent type from the table definition. Equivalent to:
//
// interface TableSchema {
//   matchId: string,                // Primary key components are not nullable
//   round: number,
//   score?: number | null,          // Non-primary key columns are optional and can return as null
//   winner?: string | null,
//   when?: DataAPITimestamp | null,
//   fighters?: Set<UUID>,           // Maps, lists, and sets are optional to insert, but returns as empty instead of null
//   mVector?: DataAPIVector | null, // Vectors can be null.
// }
//
// The preceding definition uses some custom types, like DataAPITimestamp, UUID, and DataAPIVector.
// If necessary, you can modify the ser/des logic to use different datatypes instead.
// However, you must provide your own types in that case.
// For more information, see the Typescript client usage documentation.
type TableSchema = InferTableSchema<typeof mkGamesTable>;

// Infer the TS-equivalent type of the primary key from the table definition. Equivalent to:
// type TablePK = Pick<TableSchema, 'matchId' | 'round'>;
type TablePK = InferTablePrimaryKey<typeof mkGamesTable>;

// Main function
(async function bootstrap() {
  // Call the function to actually create the table
  const table = await mkGamesTable();

  // You can then use TableSchema as you would any other type.
  // @ts-expect-error - 'badfield' is not a valid column as per the table's type
  const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

  // res.insertedId :: { matchId: string, round: number }
  const res = await table.insertOne(row);
})();
Infer from created table with ES2022 top-level await

For this strategy, you must write the table definition inline or create it with a <const> assertion. For an example of <const>, see Infer from definition object.

import { DataAPIClient, InferTablePrimaryKey, InferTableSchema } from '@datastax/astra-db-ts';

// Instantiate the client and connect to the database
const client = new DataAPIClient();
const db = client.db('ENDPOINT', { token: 'TOKEN' });

// You can use this if top-level awaits are allowed in your environment
const table = await db.createTable('games', {
  definition: {
    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 },
    },
  }
});

// Infer the TS-equivalent type from the table definition. Equivalent to:
//
// interface TableSchema {
//   matchId: string,                // Primary key components are not nullable
//   round: number,
//   score?: number | null,          // Non-primary key columns are optional and can return as null
//   winner?: string | null,
//   when?: DataAPITimestamp | null,
//   fighters?: Set<UUID>,           // Maps, lists, and sets are optional to insert, but returns as empty instead of null
//   mVector?: DataAPIVector | null, // Vectors can be null.
// }
//
// The preceding definition uses some custom types, like DataAPITimestamp, UUID, and DataAPIVector.
// If necessary, you can modify the ser/des logic to use different datatypes instead.
// However, you must provide your own types in that case.
// For more information, see the Typescript client usage documentation.
type TableSchema = InferTableSchema<typeof table>;

// Infer the TS-equivalent type of the primary key from the table definition. Equivalent to:
// type TablePK = Pick<TableSchema, 'matchId' | 'round'>;
type TablePK = InferTablePrimaryKey<typeof table>;

// You can then use `TableSchema` as you would any other type.
// @ts-expect-error - 'badfield' is not a valid column as per the table's type
const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

// res.insertedId :: { matchId: string, round: number }
const res = await table.insertOne(row);

With any of these strategies, you can use InferTableSchema and InferTableReadSchema to extract the exact read/write schemas.

For more information, see Collection and Table typing.

You can manually provide your own type for your tables by passing the type as a generic parameter to the createTable method.

Optionally, you can provide your own type for the table’s primary key as a string literal union type of the primary key column names. For more information, see Get a table object.

This may be necessary if you modify the table’s default ser/des configuration.

The following example passes the manual types MySchema and MyPK to createTable:

interface MySchema {
  matchId: string,
  round: number,
  score: number,
  winner: string,
  when: DataAPITimestamp,
  fighters: Set<UUID>,
  mVector: DataAPIVector,
}

interface MyPK = Pick<MySchema, 'matchId' | 'round'>;

(async function bootstrap() {
  const table = await db.createTable<MySchema, MyPK>('games', {
    definition: {
      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 },
      },
    }
  });

  // Use MySchema as you would any other type
  // @ts-expect-error - 'badfield' is not a valid column as per the table's type
  const row: MySchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

  // res.insertedId :: { matchId: string, round: number }
  const res = await table.insertOne(row);
})();

If you need to provide different schemas for reads and writes, see Collection and Table typing.

If you want to create a table without any typing, then you must pass SomeRow as the single generic type parameter. This types the table’s rows as Record<string, any>, which is the most flexible but least type-safe option.

(async function bootstrap() {
  const table = await db.createTable<SomeRow>('games', {
    definition: {
      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 },
      },
    }
  });

  // No typechecking anymore
  await table.insertOne({ matchId: 'match01', round: 1, badfield: 'Shhh!' })

  // res.insertedId :: SomeRow
  const res = await table.insertOne(row);
})();

By default, the client creates the table in the database’s working keyspace. To create a table in a specific keyspace, include keyspace:

const table = await db.createTable<SomeRow>('games', {
  definition: /* omitted for brevity \*/,
  keyspace: 'KEYSPACE_NAME',
});

Parameters:

Name Type Summary

name

string

The name of the table.

option?

CreateTableOptions

The options for spawning the Table instance.

Options (CreateTableOptions<Schema>):

Name Type Summary

definition

CreateTableDefinition

A TypeScript object defining the table to create, including the following:

  • columns: An object defining the table’s columns as a series of key-value pairs where each key is a column name and each value is the column’s data type. Column names must be unique within a table.

    The Data API accepts column definitions in two formats:

    "columns": {
      "COLUMN_NAME": "DATA_TYPE",
      "COLUMN_NAME": {
        "type": "DATA_TYPE"
      }
    }

    Data types are enums of supported data types, such as 'text', 'int', or 'boolean'.

    For 'map', 'list', and 'set', types, you must use the object format and provide additional options. For more information, see Map, list, and set types.

    For the 'vector' type, you must use the object format and provide information about the stored vectors, such as dimension and service options. For more information, see Vector type.

  • primaryKey: The table’s primary key definition as a single string or an object containing partition keys. For more information, see Primary keys.

ifNotExists

boolean

If true, the command doesn’t throw an error if a table with the given name already exists. In this case, the command silently does nothing and no actual table creation takes place on the database.

If false (default), an error occurs if a table with the specified name already exists in the database.

ifNotExists: true, does not check the schema of any existing tables. This parameter checks table names only.

This means that the command succeeds if the given table name is already in use, even if the schema is different.

keyspace?

string

The keyspace where you want to create the table. If not specified, the working keyspace of the Db is used.

embeddingApiKey?

string | EmbeddingHeadersProvider

Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

As an alternative to Astra DB KMS authentication, use embeddingApiKey to store an embedding provider API key on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header with operations that use vectorize.

Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

logging?

DataAPILoggingConfig

The configuration for logging events emitted by the DataAPIClient.

timeoutDefaults?

Partial<TimeoutDescriptor>

The default timeout options for any operation performed on this Table instance. For more information, see TimeoutDescriptor.

serdes?

TableSerDesConfig

Lower-level serialization/deserialization configuration for this table. For more information, see Custom Ser/Des.

Returns:

Promise<Table<Schema, PKey>> - A Promise that resolves to the Table instance representing the newly created table.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTableSchema, SomeRow, 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
const TableDefinition = <const>{                  // <const> ensures the exact literal type of the object is used, not a widened type
  columns: {
    matchId: 'text',                              // Represented by a native JS string
    round: 'tinyint',                             // All non-varint/decimal numbers are represented as JS numbers
    mVector: { type: 'vector', dimension: 3 },    // Vectors are represented as DataAPIVectors by default to enable some optimizations
    score: 'int',
    when: 'timestamp',                            // Represented by DataAPITimestamps instead of Dates
    winner: 'text',
    fighters: { type: 'set', valueType: 'uuid' }, // Sets/maps/lists are represented as native JS Sets/Maps/Arrays
  },                                              // But the UUID is represented as a provided UUID class.
  primaryKey: {
    partitionBy: ['matchId'],                     // 'matchId' is the sole partition key
    partitionSort: { round: 1 },                  // 'round' is the sole clustering key
  },
} satisfies CreateTableDefinition;                // Ensures the table definition is valid

// Infer the TS-equivalent type from the table definition. Equivalent to:
//
// interface TableSchema {
//   matchId: string,                // Primary key components are not nullable
//   round: number,
//   score?: number | null,          // Non-primary key columns are optional and can return as null
//   winner?: string | null,
//   when?: DataAPITimestamp | null,
//   fighters?: Set<UUID>,           // Maps, lists, and sets are optional to insert, but returns as empty instead of null
//   mVector?: DataAPIVector | null, // Vectors can be null.
// }
//
// The preceding definition uses some custom types, like DataAPITimestamp, UUID, and DataAPIVector.
// If necessary, you can modify the ser/des logic to use different datatypes instead.
// However, you must provide your own types in that case.
// For more information, see the Typescript client usage documentation.
type TableSchema = InferTableSchema<typeof TableDefinition>;

(async function () {
  // Create a table using the given TableSchema type or error if a 'games' table already exists
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Attempt to create the same table again.
  // This errors because a table with the given name already exists,
  // and it uses the default of 'ifNotExists: false'.
  await db.createTable<TableSchema>('games', { definition: TableDefinition })
    .catch((e => console.error(e.message)));

  // Attempt to create the same table again.
  // Because 'ifNotExists: true', the command does not throw an error
  // if the working keyspace already has an table named 'games'.
  await db.createTable<TableSchema>('games', { definition: TableDefinition, ifNotExists: true });

  // Insert a single row
  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([                             // Uses native Maps/Sets/Arrays for collections
      uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in collections
      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 createTable to create an untyped reference to the table.
  const untypedTable = await db.createTable<SomeRow>('games', { definition: TableDefinition, ifNotExists: true });

  // Attempt to insert a row into the untyped table.
  // This errors at runtime (not statically) because it's untyped.
  await untypedTable.insertOne({ matchId: '32', round: 1, badfield: 3 })
    .catch((e => console.error(e.message)));

  // The following examples demonstrate various ways to get a reference to a table (a Table object)

  // Create the table if it doesn't already exist, but don't retain the Table object
  await db.createTable('games', { definition: TableDefinition, ifNotExists: true });

  // Create an untyped table object
  const untypedTable = db.table('games');

  // Flexible but not type-safe, errors at runtime
  const inserted1 = await untypedTable.insertOne({ matchId: 'fight7' });

  // Return type of inserted primary key not known either
  console.log(inserted1.insertedId["I don't know who I am..."]);

  // Return types of find operations, not type-safe
  const found1 = await untypedTable.findOne({ matchId: 'fight7', round: 3 });
  console.log(found1?.["I guess you could say that I'm having an IDentity crisis :)"]);

  // Create a typed table object
  const typedTable = db.table<TableSchema, TablePK>('games');

  // @ts-expect-error
  // Type-safe, errors when compiling
  // You must ensure the types are correct
  const inserted2 = await typedTable.insertOne({ matchId: 'fight7' });

  // @ts-expect-error
  // Type-safe, errors when compiling
  console.log(inserted2.insertedId["uh oh I've been caught"]);

  // Still type-safe
  const found2 = await typedTable.findOne({ matchId: 'fight7', round: 3 })
  console.log(found2?.winner);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();
// Create a table using the given TableSchema type or error if a 'games' table already exists
const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

// Attempt to create the same table again.
// This errors because a table with the given name already exists,
// and it uses the default of 'ifNotExists: false'.
await db.createTable<TableSchema>('games', { definition: TableDefinition })
  .catch((e => console.error(e.message)));

// Attempt to create the same table again.
// Because 'ifNotExists: true', the command does not throw an error
// if the working keyspace already has an table named 'games'.
await db.createTable<TableSchema>('games', { definition: TableDefinition, ifNotExists: true });

// Insert a single row
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([                             // Uses native Maps/Sets/Arrays for collections
    uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in collections
    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 createTable to create an untyped reference to the table.
const untypedTable = await db.createTable<SomeRow>('games', { definition: TableDefinition, ifNotExists: true });

// Attempt to insert a row into the untyped table.
// This errors at runtime (not statically) because it's untyped.
await untypedTable.insertOne({ matchId: '32', round: 1, badfield: 3 })
  .catch((e => console.error(e.message)));

For more information, see the Client reference.

Create a table in the database’s working keyspace by providing a TableDefinition and specializations through options:

TableDefinition tableDefinition = new TableDefinition()
  .addColumnText("match_id")
  .addColumnInt("round")
  .addColumnVector("m_vector",
    new ColumnDefinitionVector().dimension(3).metric(COSINE))
  .addColumn("score", ColumnTypes.INT)
  .addColumn("when",  ColumnTypes.TIMESTAMP)
  .addColumn("winner",  ColumnTypes.TEXT)
  .addColumnSet("fighters", ColumnTypes.UUID)
  .addPartitionBy("match_id")
  .addPartitionSort(ascending("round"));

// Default Table Creation
Table<Row> tableGames = database
  .createTable("games", tableDefinition);

You can use the following optional parameters to customize the createTable operation:

  • Class<T> (rowClass): Specify the type of the table’s row object. If not provided, the default is Row.

  • CreateTableOptions: Granular control over the createTable operation itself, such as timeouts.

  • TableOptions: Options for the returned Table<T> object, such as specific timeouts for that object.

// Specify options at creation
CreateTableOptions createTableOptions = new CreateTableOptions()
 .ifNotExists(true)
 .embeddingAuthProvider(new EmbeddingAPIKeyHeaderProvider("api-key"))
 .timeout(ofSeconds(5));

Table<Row> tableGames = database
 .createTable("games", tableDefinition, createTableOptions);

// Change the Type of objects in use instead of default Row
Table<Game> tableGames = database
 .createTable(
    "games",            // table name
    tableDefinition,    // table definition
    Game.class,         // bean for row
    createTableOptions);

Additionally, instead of explicitly defining the TableDefinition, you can use annotations to define the schema directly in your POJOs.

For example, given the following bean:

@EntityTable("game_ann1")
public class GameAnn1 {

    @PartitionBy(0)
    @Column(name ="match_id", type=TEXT )
    private String matchId;

    @PartitionSort(position = 0, order= SortOrder.ASCENDING)
    @Column(name ="round", type=INT)
    private Integer round;

    @Column(name ="score", type=INT)
    private Integer score;

    @Column(name ="when", type=TIMESTAMP)
    private Instant when;

    @Column(name ="winner", type=TEXT)
    private String winner;

    @Column(name ="fighters", type=SET, valueType = UUID)
    private Set<java.util.UUID> fighters;

    @Column(name ="m_vector", type=VECTOR, dimension = 3, metric = SimilarityMetric.COSINE)
    private DataAPIVector vector;
}

The following command creates a table with the name game_ann1 using the schema defined in the previously described GameAnn1 class:

Table<GameAnn1> tablGameAnn1 = database
  .createTable(GameAnn1.class);

However, there are two ways to optimize the class:

  • If the column names in the POJO match the field names, then you can omit the property name in the @Column annotation.

  • If the column types in the POJO aren’t ambiguous, then you can omit the property type in the @Column annotation.

The resulting simplified class is as follows:

@Data
@EntityTable("game_ann2")
public class Game {

    private Integer score;
    private Instant when;
    private String winner;
    private Set<UUID> fighters;

    @PartitionBy(0)
    @Column(name ="match_id")
    private String matchId;

    @PartitionSort(position = 0, order = SortOrder.ASCENDING)
    private Integer round;

    @Column(name ="m_vector", dimension = 3)
    private DataAPIVector vector;

    // getter, setters, constructor
}

Parameters:

Name Type Summary

name

String

The name of the table.

definition

TableDefinition

A complete table definition for the table, including the column names, data types, other column settings, and the primary key.

Some types require specific column definitions, particularly maps, lists, sets, and vector columns. For more information about all types, see Column data types.

rowClass

Class<?>

An optional specification of the class of the table’s row object. If not provided, the default is Row, which is close to a Map object.

createTableOptions

CreateTableOptions

Options and additional parameters for the createTable operation, such as ifNotExists, timeout, and embeddingAuthProvider:

  • ifNotExists(): If true, the command doesn’t throw an error if a table with the given name already exists. In this case, the command silently does nothing and no actual table creation takes place on the database.

    If false (default), an error occurs if a table with the specified name already exists in the database.

    ifNotExists(true), does not check the definition of any existing tables. This parameter checks table names only.

    This means that the command succeeds if the given table name is already in use, even if the table definition is different.

  • timeout(): A timeout, in milliseconds, to impose on the underlying API request.

  • embeddingAuthProvider(): Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

    As an alternative to Astra DB KMS authentication, use embeddingAuthProvider to store an embedding provider API key on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header with operations that use vectorize.

    Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

Returns:

Table<T> - A Table object that is typed as Table<Row> by default. To provide a more specific type hint, you must pass the rowClass parameter matching the appropriate type hint for the variable used in the assignment. For more information, see the following example.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.core.auth.EmbeddingAPIKeyHeaderProvider;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Game;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.definition.TableDefinition;
import com.datastax.astra.client.tables.TableOptions;
import com.datastax.astra.client.tables.definition.columns.ColumnDefinitionVector;
import com.datastax.astra.client.tables.definition.columns.ColumnTypes;
import com.datastax.astra.client.tables.commands.options.CreateTableOptions;
import com.datastax.astra.client.tables.definition.rows.Row;

import static com.datastax.astra.client.core.query.Sort.ascending;
import static com.datastax.astra.client.core.vector.SimilarityMetric.COSINE;
import static java.time.Duration.ofSeconds;

public class CreateTable {

 public static void main(String[] args) {
  // Database astraDb = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();

  // Definition of the table in fluent style
  TableDefinition tableDefinition = new TableDefinition()
   .addColumnText("match_id")
   .addColumnInt("round")
   .addColumnVector("m_vector", 
     new ColumnDefinitionVector().dimension(3).metric(COSINE))
   .addColumn("score", ColumnTypes.INT)
   .addColumn("when",  ColumnTypes.TIMESTAMP)
   .addColumn("winner",  ColumnTypes.TEXT)
   .addColumnSet("fighters", ColumnTypes.UUID)
   .addPartitionBy("match_id")
   .addPartitionSort(ascending("round"));


  // Minimal creation
  Table<Row> table1 =
    db.createTable("games", tableDefinition);

  // Minimal Creation with a Bean
  Table<Game> table2 =
    db.createTable("game2", tableDefinition, Game.class);

  // One can add options to setup the creation with finer grained:
  CreateTableOptions createTableOptions = new CreateTableOptions()
   .keyspace("ks2")
   .ifNotExists(true)
   .embeddingAuthProvider(new EmbeddingAPIKeyHeaderProvider("api-key"))
   .timeout(ofSeconds(5));
  Table<Row> table3 =
    db.createTable("game3", tableDefinition, createTableOptions);
 }
}

To create a table, the JSON payload must include the table name, column definitions, and primary key definition.

The format of column definitions depends on the column’s data type. For more information, see definition.columns in this command’s Parameters table.

The primary key definition depends on the primary key type. The following examples demonstrate the JSON for the three primary key types. For more information, see Primary keys.

  • Single-column primary key

  • Composite primary key

  • Compound primary key

Create a table with a single-column primary key:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "TABLE_NAME",
    "definition": {
      "columns": {
        "COLUMN_NAME": "DATA_TYPE",
        "COLUMN_NAME": "DATA_TYPE"
      },
      "primaryKey": "COLUMN_NAME"
    }
  }
}' | jq

Create a table with a composite primary key:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "TABLE_NAME",
    "definition": {
      "columns": {
        "COLUMN_NAME": {
          "type": "DATA_TYPE"
        },
        "COLUMN_NAME": {
          "type": "DATA_TYPE"
        }
      },
      "primaryKey": {
        "partitionBy": [
          "COLUMN_NAME", "COLUMN_NAME"
        ]
      }
    }
  }
}' | jq

Create a table with a compound primary key:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "TABLE_NAME",
    "definition": {
      "columns": {
        "COLUMN_NAME": {
          "type": "DATA_TYPE"
        },
        "COLUMN_NAME": {
          "type": "DATA_TYPE"
        }
      },
      "primaryKey": {
        "partitionBy": [
          "PARTITION_COLUMN_NAME"
        ]
        "partitionSort": {
          "SORT_COLUMN_NAME": -1
        }
      }
    }
  }
}' | jq

To store pre-generated vectors in a table, you must define a vector column:

      "columns": {
        "COLUMN_NAME": "DATA_TYPE",
        "COLUMN_NAME": "DATA_TYPE",
        "VECTOR_COLUMN_NAME": {
          "type": "vector",
          "dimension": NUM_DIMENSIONS
        }
      }

To automatically generate embeddings with vectorize, define a vector column with embedding provider service options. Astra DB stores the automatically-generated embeddings in this column.

      "columns": {
        "COLUMN_NAME": "DATA_TYPE",
        "COLUMN_NAME": "DATA_TYPE",
        "VECTOR_COLUMN_NAME": {
          "type": "vector",
          "dimension": NUM_DIMENSIONS,
          "service": {
            "provider": "EMBEDDINGS_PROVIDER_NAME",
            "modelName": "MODEL_NAME",
            "authentication": {
              "providerKey": "ASTRA_KMS_API_KEY_NAME",
            }
          }
        }
      }

You can alter vector columns at any time to change the vector configuration, including adding or removing a vectorize integration.

For more information about all aspects of vectors in tables, see Vector type.

Parameters:

Name Type Summary

createTable

command

The Data API command to create a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to create the table.

name

string

The name of the table. This must be unique within the database specified in the request URL.

definition

object

Contains the columns and primary key definition for the table.

definition.columns

object

Defines the table’s columns as a series of key-value pairs where each key is a column name and each value is the column’s data type. Column names must be unique within a table.

The Data API accepts column definitions in two formats:

"columns": {
  "COLUMN_NAME": "DATA_TYPE",
  "COLUMN_NAME": {
    "type": "DATA_TYPE"
  }
}

Data types are enums of supported data types, such as "text", "int", or "boolean".

For map, list, and set, types, you must use the object format and provide additional options. For more information, see Map, list, and set types.

For the vector type, you must use the object format and provide information about the stored vectors, such as dimension and service options. For more information, see Vector type.

definition.primaryKey

string or object

Defines the primary key for the table. For more information, see Primary keys.

Returns:

A successful request returns 200 OK.

Example response
{
  "status": {
    "ok": 1
  }
}

Examples:

Create a table with a single-column primary key
curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "students",
    "definition": {
      "columns": {
        "name": "text",
        "email": "text",
        "graduated": "boolean",
        "graduation_year": {
          "type": "int"
        },
        "semester_gpas": {
          "type": "list",
          "valueType": "decimal"
        },
        "grades": {
          "type": "map",
          "keyType": "text",
          "valueType": "int"
        },
        "extracurriculars": {
          "type": "set",
          "valueType": "text"
        },
        "vect_emb": {
          "type": "vector",
          "dimension": 1024
        }
      },
      "primaryKey": "email"
    }
  }
}' | jq
Create a table with a composite primary key
curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "students",
    "definition": {
      "columns": {
        "name": "text",
        "email": "text",
        "graduated": "boolean",
        "graduation_year": {
          "type": "int"
        },
        "semester_gpas": {
          "type": "list",
          "valueType": "decimal"
        },
        "grades": {
          "type": "map",
          "keyType": "text",
          "valueType": "int"
        },
        "extracurriculars": {
          "type": "set",
          "valueType": "text"
        },
        "vect_emb": {
          "type": "vector",
          "dimension": 1024
        }
      },
      "primaryKey": {
        "partitionBy": [
          "name", "email"
        ]
      }
    }
  }
}' | jq
Create a table with a compound primary key
curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "createTable": {
    "name": "students",
    "definition": {
      "columns": {
        "name": "text",
        "email": "text",
        "graduated": "boolean",
        "graduation_year": {
          "type": "int"
        },
        "semester_gpas": {
          "type": "list",
          "valueType": "decimal"
        },
        "grades": {
          "type": "map",
          "keyType": "text",
          "valueType": "int"
        },
        "extracurriculars": {
          "type": "set",
          "valueType": "text"
        },
        "vect_emb": {
          "type": "vector",
          "dimension": 1024
        }
      },
      "primaryKey": {
        "partitionBy": [
          "graduation_year"
        ],
        "partitionSort": {
          "email": -1
        }
      }
    }
  }
}' | jq

Primary keys

The primary key is the unique identifier for rows in a table.

When you create a table, you define a primary key schema consisting of one or more columns. Column defined in the primary key are automatically indexed and available for querying. For more information about the role of indexes in tables, see Work with table indexes.

You cannot use map, list, or set columns in primary keys.

Due to a known issue with filtering on blob columns, DataStax does not recommend using blob columns in primary keys.

There are three types of primary keys that you can define. The type of key you use depends on your data model and the types of queries you plan to run. The format of the primaryKey in your table definition depends on the primary key type.

  • Single-column primary key

  • Composite primary key

  • Compound primary key

A single-column primary key is a primary key consisting of one column.

This option is best for use cases where you usually retrieve rows by a single value. For example, you could use this strategy for a small customer database where every customer is uniquely identified by their email address, and you always look up customers by their email address.

To define a single-column primary key, the primaryKey is the column name as a string:

"primaryKey": "COLUMN_NAME"

For client-specific representations and more examples, see Create a table.

A composite primary key is a primary key consisting of multiple columns. The rows are uniquely identified by the combination of the values from each column.

This strategy can make queries more efficient by creating partitions (groups) of rows based on each primary key column. For example, if your primary key includes country and city, the database has implicit groups of rows with the same country or city, making it more efficient to search for rows in a specific country or city.

This is a moderately complex strategy that allows for more nuanced queries and more complex unique identifiers. It can be useful if your rows are uniquely defined by values from multiple columns or your data falls into natural groupings, such as location or time. For example, you could use this strategy for scenarios such as the following:

  • A manufacturing database that uniquely identifies products by the production date, factory location, and SKU

  • A global customer database that groups customers by country or locality, in addition to an identifier, such as customer ID or email address

For composite primary keys, avoid columns with low cardinality (low diversity of values). For example, a customer database with an overabundance of customers from a single country might not benefit from partitioning by country. Instead, you could use locality identifiers, such as states or postal codes, to break large customer segments into smaller groups for more efficient queries.

To define a composite primary key, the primaryKey is an object containing a partitionBy array that contains the names of the columns to use for partitioning:

"primaryKey": {
  "partitionBy": [
    "COLUMN_NAME", "COLUMN_NAME"
  ]
}

For client-specific representations and more examples, see Create a table.

A compound primary key is a primary key consisting of partition (grouping) columns and clustering (sorting) columns. The rows are uniquely identified by the combination of the values from each column.

This is the most complex partitioning strategy, but it can provide the most flexibility and efficiency for querying data, if it is appropriate for your data model. This strategy can be useful for scenarios where you need to perform range queries or sort time-series data.

For example, assume you have a retail database where each row represents an order, and the orders are partitioned by customer ID and clustered by purchase date. In this case, the database implicitly groups each customer’s order together, and then sorts each customer’s orders by purchase date. This can make it more efficient to retrieve a customer’s most recent orders when they contact customer service or when they check the status of their orders in their account.

You can have multiple partition columns and multiple clustering columns. When clustering on multiple columns, the order you declare the columns matters. For example, if you cluster by date and name, the data is first sorted by the date, and then any rows with the same date are sorted by name.

In compound primary keys, avoid choosing clustering columns with high cardinality (high diversity of values), depending on your data model. For example, a purchase number column may not be ideal for clustering because it is unlikely to contain duplicates. Instead, choose clustering columns with moderate cardinality, such as purchase date, while avoiding columns with extremely low cardinality, such as booleans.

To define a compound primary key, the primaryKey value is an object containing a partitionBy array and a partitionSort object:

  • partitionBy is an array that contains the names of one or more columns to use for partitioning.

  • partitionSort is an object that contains key-value pairs defining clustering columns and the desired sort behavior. -1 indicates descending sorting and 1 indicates ascending sorting.

    If partitionSort has multiple columns, sorting occurs in the order the columns are defined in the partitionSort object.

partitionBy and partitionSort must use different columns.

"primaryKey": {
  "partitionBy": [
    "PARTITION_COLUMN_NAME",
    "PARTITION_COLUMN_NAME"
  ],
  "partitionSort": {
    "SORT_COLUMN_NAME": -1,
    "SORT_COLUMN_NAME": 1
  }
}

For client-specific representations and more examples, see Create a table.

Get a table object

Get a reference to an existing table for use with Data API clients.

This command returns a Table object even for tables that don’t exist. Makes sure the table exists before running this command because the command doesn’t check for you.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Get a Table object from a Database using the working keyspace of the Database:

my_table = database.get_table("games")

By default, get_table uses the database’s working keyspace.

If necessary, you can specify a different keyspace, and you can pass other options for the resulting Table object, such as an embedding_api_key for header-based vectorize authentication:

my_table = database.get_table(
    "games",
    keyspace="the_other_keyspace",
    embedding_api_key="secret-012abc...",
)

Get a typed Table object by supplying a type (a subclass of TypedDict) to its rows:

my_typed_table: Table[MyCustomDictType] = database.get_table(
    "games",
    row_type=MyCustomDictType,
)

Parameters:

Name Type Summary

name

str

The name of the table.

row_type

type

This parameter acts a formal specifier for the type checker. If omitted, the resulting Table is implicitly a Table[dict]. If provided, row_type must match the type hint specified in the assignment. For more information, see Typing support.

keyspace

str | None

The keyspace containing the target table. If not specified, the general keyspace setting for the database is used.

embedding_api_key

str | EmbeddingHeadersProvider

Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

As an alternative to Astra DB KMS authentication, use embedding_api_key to store one or more embedding provider API keys on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header (EmbeddingAPIKeyHeaderProvider) with operations that use vectorize.

Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

spawn_api_options

APIOptions

A complete or partial specification of the APIOptions to override the defaults inherited from the Database. This allows for nuanced table configuration. For example, if APIOptions is passed together with named timeout parameters, the latter take precedence in their respective settings.

Returns:

Table - A Table object that is typed as Table[dict] by default. To provide a more specific type hint, you must pass the row_type parameter matching the appropriate type hint for the variable used in the assignment. For more information, see the Example for this command.

Example response (reformatted for clarity)
Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

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

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()
    ),
)

# Get a Table object (and read a property of it as an example):
my_table = database.get_table("games")
my_table.full_name
# 'default_keyspace.games'

# Get a Table object in a specific keyspace,
# and set an embedding API key to it:
my_other_table = database.get_table(
    "tournaments",
    keyspace="the_other_keyspace",
    embedding_api_key="secret-012abc...",
)

from astrapy import Table
MyCustomDictType = dict[str, int]

# Get a Table object typed with a specific type for its rows:
my_typed_table: Table[MyCustomDictType] = database.get_table(
    "games",
    row_type=MyCustomDictType,
)

For more information, see the Client reference.

To spawn a Table instance, you must pass a type schema. The TypeScript client offers several ways to type tables, depending on your typing preferences and needs.

  • Schema

  • Schema and primary key

  • Untyped

  • Full generic type signature

The most straightforward way to type a table is to provide a schema object that represents the table’s structure. However, this strategy doesn’t provide any type information about the table’s primary key.

import { DataAPIClient, DataAPITimestamp, DataAPIVector, UUID } 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! });

// Define table's type manually
interface TableSchema {
  matchId: string,
  round: number,
  score: number,
  winner: string,
  when: DataAPITimestamp,
  fighters: Set<UUID>,
  mVector: DataAPIVector,
}

// Pass it to db.table to type it as such.
// You must ensure the schema matches the table's actual schema.
const table = db.table<TableSchema>('games');

// You can then use TableSchema as you would any other type.
// @ts-expect-error - 'badfield' is not a valid column as per the table's type
const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

// res.insertedId :: Partial<TableSchema>
const res = await table.insertOne(row);

The primary key type is used in the return types of insertOne and insertMany operations only. However, you don’t need to specify the primary key type if you use the default Partial<Schema> as the primary key type or you don’t need to use the returned values from insertOne and insertMany operations.

Partial<Schema> keeps the return type type-safe when the primary key fields are not known. For example, given the following schema:

interface SchemaWithNoPK {
  ptKey: string, // We know this is part of the primary key; TypeScript doesn't
  clKey: string,
  val1?: string | null,
  val2?: number | null,
}
const table = db.table<SchemaWithNoPK>('my_table');

If there is no primary key information provided, then insertOne returns an insertedId like the following:

// `insertedId` is inferred to be `Partial<SchemaWithNoPK>` by default
const inserted = await table.insertOne({ ptKey: 'abc', clKey: 'def', val1: 'val' });
const insertedId = inserted.insertedId;

While not perfect, this option remains relatively type-safe without necessitating that you embed your primary key’s type in the table’s schema’s type itself.

If the primary key type is unspecified, the actual default is Partial<RSchema>, but the difference between Partial<RSchema> and Partial<Schema> is negligible for most use cases. For more information about read and write schemas, see Full generic type signature.

For more precise typing, you can include the primary key information in the table’s type along with the schema. This strategy requires the TS-native Pick utility type to define the primary key type.

import { DataAPIClient, DataAPITimestamp, DataAPIVector, UUID } 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! });

// Define table's type manually
interface TableSchema {
  matchId: string,
  round: number,
  score: number,
  winner: string,
  when: DataAPITimestamp,
  fighters: Set<UUID>,
  mVector: DataAPIVector,
}

// Define table's primary key type
type TablePK = Pick<TableSchema, 'matchId' | 'round'>;

// Pass it to db.table to type it as such.
// You must ensure the schema matches the table's actual schema.
const table = db.table<TableSchema, TablePK>('games');

// You can then use TableSchema as you would any other type.
// @ts-expect-error - 'badfield' is not a valid column as per the table's type
const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

// res.insertedId :: { matchId: string, round: number }
const res = await table.insertOne(row);

If you want to use a table without any typing, you can pass SomeRow as the single generic type parameter. This types the table’s rows as Record<string, any>, which is the most flexible but least type-safe option.

import { DataAPIClient } 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! });

// Pass it to db.table to type it as such.
// You must ensure the schema matches the table's actual schema.
const table = db.table<TableSchema, TablePK>('games');

// You can then use TableSchema as you would any other type.
// @ts-expect-error - 'badfield' is not a valid column as per the table's type
const row: TableSchema = { matchId: 'match01', round: 1, badfield: 'Shhh!' }

// res.insertedId :: { matchId: string, round: number }
const res = await table.insertOne(row);

For the most complex use cases, especially when using custom ser/des logic, consider using the Table full generic type signature:

class Table<
  WSchema extends SomeRow,
  PKey extends SomeRow = Partial<FoundRow<WSchema>>,
  RSchema extends SomeRow = FoundRow<WSchema>,
> {}

For more information, see Collection and Table typing.

Parameters:

Name Type Summary

name

string

The name of the table.

option?

TableOptions

The options for spawning the Table instance.

Options (TableOptions<Schema>):

Name Type Summary

keyspace?

string

The keyspace where the target table exists. If not specified, the working keyspace of the Db is used. For example:

const table = db.table<Schema>('games', {
  keyspace: 'KEYSPACE',
});

embeddingApiKey?

string | EmbeddingHeadersProvider

Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

As an alternative to Astra DB KMS authentication, use embeddingApiKey to store an embedding provider API key on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header with operations that use vectorize.

Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

logging?

DataAPILoggingConfig

The configuration for logging events emitted by the DataAPIClient.

timeoutDefaults?

Partial<TimeoutDescriptor>

The default timeout options for any operation performed on this Table instance. For more information, see TimeoutDescriptor.

serdes?

TableSerDesConfig

Lower-level serialization/deserialization configuration for this table. For more information, see Custom Ser/Des.

Returns:

Table<Schema> - An unvalidated reference to the table. The type parameter Schema is used for type inference in the client library. You must ensure that the schema matches the actual table schema.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTableSchema, SomeRow, 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
const TableDefinition = <const>{                  // <const> ensures the exact literal type of the object is used, not a widened type
  columns: {
    matchId: 'text',                              // Represented by a native JS string
    round: 'tinyint',                             // All non-varint/decimal numbers are represented as JS numbers
    mVector: { type: 'vector', dimension: 3 },    // Vectors are represented as DataAPIVectors by default to enable some optimizations
    score: 'int',
    when: 'timestamp',                            // Represented by DataAPITimestamps instead of Dates
    winner: 'text',
    fighters: { type: 'set', valueType: 'uuid' }, // Sets/maps/lists are represented as native JS Sets/Maps/Arrays
  },                                              // But the UUID is represented as a provided UUID class.
  primaryKey: {
    partitionBy: ['matchId'],                     // 'matchId' is the sole partition key
    partitionSort: { round: 1 },                  // 'round' is the sole clustering key
  },
} satisfies CreateTableDefinition;                // Ensures the table definition is valid

// Infer the TS-equivalent type from the table definition. Equivalent to:
//
// interface TableSchema {
//   matchId: string,                // Primary key components are not nullable
//   round: number,
//   score?: number | null,          // Non-primary key columns are optional and can return as null
//   winner?: string | null,
//   when?: DataAPITimestamp | null,
//   fighters?: Set<UUID>,           // Maps, lists, and sets are optional to insert, but returns as empty instead of null
//   mVector?: DataAPIVector | null, // Vectors can be null.
// }
//
// The preceding definition uses some custom types, like DataAPITimestamp, UUID, and DataAPIVector.
// If necessary, you can modify the ser/des logic to use different datatypes instead.
// However, you must provide your own types in that case.
// For more information, see the Typescript client usage documentation.
type TableSchema = InferTableSchema<typeof TableDefinition>;

(async function () {
  // Create a table using the given TableSchema type or error if a 'games' table already exists
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Attempt to create the same table again.
  // This errors because a table with the given name already exists,
  // and it uses the default of 'ifNotExists: false'.
  await db.createTable<TableSchema>('games', { definition: TableDefinition })
    .catch((e => console.error(e.message)));

  // Attempt to create the same table again.
  // Because 'ifNotExists: true', the command does not throw an error
  // if the working keyspace already has an table named 'games'.
  await db.createTable<TableSchema>('games', { definition: TableDefinition, ifNotExists: true });

  // Insert a single row
  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([                             // Uses native Maps/Sets/Arrays for collections
      uuid('a4e4e5b0-1f3b-4b4d-8e1b-4e6b3f1f3b4d'), // You can nest datatypes in collections
      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 createTable to create an untyped reference to the table.
  const untypedTable = await db.createTable<SomeRow>('games', { definition: TableDefinition, ifNotExists: true });

  // Attempt to insert a row into the untyped table.
  // This errors at runtime (not statically) because it's untyped.
  await untypedTable.insertOne({ matchId: '32', round: 1, badfield: 3 })
    .catch((e => console.error(e.message)));

  // The following examples demonstrate various ways to get a reference to a table (a Table object)

  // Create the table if it doesn't already exist, but don't retain the Table object
  await db.createTable('games', { definition: TableDefinition, ifNotExists: true });

  // Create an untyped table object
  const untypedTable = db.table('games');

  // Flexible but not type-safe, errors at runtime
  const inserted1 = await untypedTable.insertOne({ matchId: 'fight7' });

  // Return type of inserted primary key not known either
  console.log(inserted1.insertedId["I don't know who I am..."]);

  // Return types of find operations, not type-safe
  const found1 = await untypedTable.findOne({ matchId: 'fight7', round: 3 });
  console.log(found1?.["I guess you could say that I'm having an IDentity crisis :)"]);

  // Create a typed table object
  const typedTable = db.table<TableSchema, TablePK>('games');

  // @ts-expect-error
  // Type-safe, errors when compiling
  // You must ensure the types are correct
  const inserted2 = await typedTable.insertOne({ matchId: 'fight7' });

  // @ts-expect-error
  // Type-safe, errors when compiling
  console.log(inserted2.insertedId["uh oh I've been caught"]);

  // Still type-safe
  const found2 = await typedTable.findOne({ matchId: 'fight7', round: 3 })
  console.log(found2?.winner);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();

Expand the preceding Full script example for the definition of TypeSchema that is used in the following truncated example:

// Create the table if it doesn't already exist, but don't retain the Table object
await db.createTable('games', { definition: TableDefinition, ifNotExists: true });

// Create an untyped table object
const untypedTable = db.table('games');

// Flexible but not type-safe, errors at runtime
const inserted1 = await untypedTable.insertOne({ matchId: 'fight7' });

// Return type of inserted primary key not known either
console.log(inserted1.insertedId["I don't know who I am..."]);

// Return types of find operations, not type-safe
const found1 = await untypedTable.findOne({ matchId: 'fight7', round: 3 });
console.log(found1?.["I guess you could say that I'm having an IDentity crisis :)"]);

// Create a typed table object
const typedTable = db.table<TableSchema, TablePK>('games');

// @ts-expect-error
// Type-safe, errors when compiling
// You must ensure the types are correct
const inserted2 = await typedTable.insertOne({ matchId: 'fight7' });

// @ts-expect-error
// Type-safe, errors when compiling
console.log(inserted2.insertedId["uh oh I've been caught"]);

// Still type-safe
const found2 = await typedTable.findOne({ matchId: 'fight7', round: 3 })
console.log(found2?.winner);

For more information, see the Client reference.

Get a Table object from a Database using the working keyspace of the Database:

Table<Row> myTable = database.getTable("games");

By default, getTable uses the database’s working keyspace.

If necessary, you can specify a different keyspace, and you can pass other options for the resulting Table object, such as an embeddingApiKey for header-based vectorize authentication:

TableOptions options = new TableOptions()
 .keyspace("the_other_keyspace")
 .embeddingApiKey("secret-012abc...");
Table<Row> myTable = db.getTable("games", options);

Get a typed Table object by supplying a type to its rows:

TableOptions options = new TableOptions();
Table<Game> myTable = database
  .getTable("games", Game.class, options);

Parameters:

Name Type Summary

name

String

The name of the table.

rowClass

Class<?>

An optional specification of the class of the table’s row object. If not provided, the default is Row, which is close to a Map object.

tableOptions

TableOptions

Specialization of the Table object overriding default configuration (DataAPIOptions).

Options:

Name Type Summary

keyspace

String

The keyspace containing the target table. If not specified, the working keyspace of the Database is used.

timeout

long or Duration

Optional configuration for default timeouts for table operations using this Table object. This is a general method for all operations.

databaseAdditionalHeaders

Map<String, String>

Optional specialized headers for this table, if needed, that are added to the database headers.

embeddingApiKey

String

Optional parameter for tables that have a vector column with a vectorize embedding provider integration. For more information, see Define a column to automatically generate vector embeddings.

As an alternative to Astra DB KMS authentication, use embeddingApiKey to store an embedding provider API key on the Table instance for vectorize header authentication. The client automatically passes the key as an X-embedding-api-key header with operations that use vectorize.

Most embedding provider integrations accept a plain string for header authentication. However, some vectorize providers and models require specialized subclasses of EmbeddingHeadersProvider for header authentication.

EmbeddingHeadersProvider

EmbeddingHeadersProvider

An optional specialization associated with embeddingApiKey.

httpClientOptions

HttpClientOptions

Optional HTTP configuration overrides for this Table instance.

serializer

DataAPISerializer

Optional specialized serializer for this Table instance. If not provided RowSerializer is used.

Returns:

Table<T> - A Table object that is typed as Table<Row> by default. To provide a more specific type hint, you must pass the rowClass parameter matching the appropriate type hint for the variable used in the assignment. For more information, see the following example.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.core.auth.EmbeddingAPIKeyHeaderProvider;
import com.datastax.astra.client.core.options.DataAPIClientOptions;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Game;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.TableOptions;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.util.Map;

public class GetTable {

 public static void main(String[] args) {
  // Database astraDb =  new DataAPIClient(token).getDatabase(endpoint);
  Database db =
    DataAPIClients.localDbWithDefaultKeyspace();

  // Default
  Table<Row> myTable1 =
   db.getTable("games");

  // Options
  TableOptions options = new TableOptions()
    .keyspace("the_other_keyspace")
    .embeddingApiKey("secret-012abc...")
    .databaseAdditionalHeaders(Map.of("Feature-Flag-tables", "true"));
  Table<Row> myTable3 = db.getTable("games", options);

  // Typing
  Table<Game> myTable2 =
   db.getTable("games", Game.class);

  // Typing + Options
  Table<Game> myTable4 =
   db.getTable("games", Game.class, new TableOptions());
 }
}

This operation is not required with HTTP because you specify the target table in the path or body of the request, if required.

To get information about tables in a database, see List table metadata.

Alter a table

Modify the configuration of a previously-created table:

The Data API does not support operations that alter a column’s type or rename a table. To achieve either of these goals, you must drop and recreate the column or table.

Add columns

Add one or more columns to an existing table. Columns are defined in the same way as they are when you create a table.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Add a column to a table:

my_table.alter(
    AlterTableAddColumns(
        columns={
            "tie_break": TableScalarColumnTypeDescriptor(
                column_type=ColumnType.BOOLEAN,
            ),
        },
    ),
)

Add columns to a table, and use the return value for strict control over types:

new_table: Table[MyCustomDictType] = my_table.alter(
    AlterTableAddColumns(
        columns={
            "tie_break": TableScalarColumnTypeDescriptor(
                column_type=ColumnType.BOOLEAN,
            ),
            "venue": TableScalarColumnTypeDescriptor(
                column_type=ColumnType.TEXT,
            ),
        },
    ),
    row_type=MyCustomDictType,
)

Parameters:

Name Type Summary

operation

AlterTableAddColumns | dict

An instance of AlterTableAddColumns detailing the name and data type for each column to be added. This is the same method used to drop columns and add/drop vectorize integrations. This parameter selects which alter operation to performe based on the object provided. Passing a regular dictionary such as {"add": {"columns": …​}} achieves the same effect.

row_type

type

This parameter acts a formal specifier for the type checker. If omitted, the resulting Table is implicitly a Table[dict[str, Any]]. If provided, it must match the type hint specified in the assignment. For more information, see Typing support.

table_admin_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:

Table - A new Table instance formally representing the table after the schema change. While you can continue working with the original class instance, stricter typing is achieved by providing a type hint to the new shape of the rows in the table, with a proper subclass of TypedDict, and using the return value of this method immediately.

Example response (reformatted for clarity)
Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

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()
    ),
)

from astrapy.info import (
    AlterTableAddColumns,
    ColumnType,
    TableScalarColumnTypeDescriptor,
)

# Add a column
new_table = my_table.alter(
    AlterTableAddColumns(
        columns={
            "tie_break": TableScalarColumnTypeDescriptor(
                column_type=ColumnType.BOOLEAN,
            ),
        },
    ),
)

For more information, see the Client reference.

Add columns to the table, and update the Table type:

const newTable = await table.alter<NewSchema>({
  operation: {
    add: {
      columns: {
        tieBreak: 'boolean',
        venue: 'text',
      },
    },
  },
});

Parameters:

Name Type Summary

operation.add

AddColumnOperation

Defines an operation to alter a table by adding one or more columns.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Options (AddColumnOperation):

Name Type Summary

columns

CreateTableColumnDefinitions

The column names, data types, and other settings (if required) for the new columns.

Column are defined in the same way as they are in createTable.

Returns:

Promise<Table<NewSchema>> - A promise which resolves to the table object recast as its new type after the alter operation.

Don’t use the original table type. Continuing to use the original table’s type causes the type of the table to desync from the table’s actual schema.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema } 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.
// For information about table definition and data types, 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;

// Infer the table type from the table definition.
// For information about table typing, see the documentation for create table.
type TableSchema = InferTableSchema<typeof TableDefinition>;

// The following script demonstrates all alter operations: add, drop, addVectorize, dropVectorize.
// This example also inserts rows to demonstrate the goal and outcome of each alter operation.
// You can only run one alter operation at a time, but you can have multiple operations in the same script.
(async function () {
  // Create a table or error if a 'games' table already exists.
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Represents the new schema of the table after the alter to add columns
  type NewSchema = TableSchema & {
    tieBreak: boolean;
    venue: string;
  }

  // @ts-expect-error
  // Try to insert data into nonexistent columns.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  // Columns are defined in the same way that you define them in createTable, including name, type, and other properties.
  const altered = await table.alter<NewSchema>({
    operation: {
      add: {
        columns: {
          tieBreak: 'boolean',
          venue: 'text',
        },
      },
    },
  });

  // Attempt to insert the rows again.
  // This should succeed now that all columns exist in the table.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' });
  console.log('inserted', inserted.insertedId);

  // Represents the new schema of the table after the alter to drop columns
  type NewSchema = Omit<TableSchema, 'tieBreak' | 'venue'>

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  const altered = await table.alter<NewSchema>({
    operation: {
      drop: {
        columns: ['tieBreak', 'venue'],
      },
    },
  });

  // @ts-expect-error
  // Try to insert data into the removed columns.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // @ts-expect-error
  // Try to use vectorize on a vector column that doesn't have a vectorize integration.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Add the OpenAI embedding provider integration to the vector column.
  const altered = await table.alter({
    operation: {
      addVectorize: {
        columns: {
          mVector: {
            provider: 'openai',
            modelName: 'text-embedding-3-small',
            authentication: {
              providerKey: 'ASTRA_KMS_API_KEY_NAME',
            },
          },
        },
      },
    },
  });

  // Attempt to insert the row again.
  // This should succeed now that the vector column has a vectorize integration.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' });
  console.log('inserted', inserted.insertedId);

  // Remove vectorize from the specified vector column
  const altered = await table.alter({
    operation: {
      dropVectorize: {
        columns: ['mVector'],
      },
    },
  });

  // @ts-expect-error
  // Try to use vectorize on the vector column that no longer has a vectorize integration.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();

Expand the preceding Full script example for the definition of NewSchema that is used in the following truncated example:

// @ts-expect-error
// Try to insert data into nonexistent columns.
// This should error both statically and at runtime.
await table.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
  .catch(e => console.error(e.message));

// Provide the new type of the table as it would be after the alter.
// Note that this just returns the same Table object, but re-casted as the proper type.
// Columns are defined in the same way that you define them in createTable, including name, type, and other properties.
const altered = await table.alter<NewSchema>({
  operation: {
    add: {
      columns: {
        tieBreak: 'boolean',
        venue: 'text',
      },
    },
  },
});

// Attempt to insert the rows again.
// This should succeed now that all columns exist in the table.
const inserted = await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' });
console.log('inserted', inserted.insertedId);

For more information, see the Client reference.

Add a column to a table:

AlterTableAddColumns alterOperation = new AlterTableAddColumns()
  .addColumnBoolean("tie_break");
Table<Game> tableRow = myTable.alter(alterOperation);

Add columns to a table, providing a new row type, and specialize some options:

AlterTableAddColumns alterOperation = new AlterTableAddColumns()
  .addColumnBoolean("tie_break")
  .addColumnText("venue");
AlterTableOptions  alterOptions = new AlterTableOptions()
  .timeout(10000L);
// Notice the type hint for the new table
Table<EnhanceGame> myUpdatedTable = myTable
  .alter(alterOperation, alterOptions, EnhanceGame.class);

Parameters:

Name Type Summary

operation

AlterTableAddColumns

Defines an operation to alter a table by adding one or more columns.

options

AlterTableOptions

Specialization of the operation, including timeout.

rowClass

Class<?>

An optional new type for the row object. If not provided, the default is Row, which is like a Map object.

Returns:

Table<NewBean> - The table object recast as its new type after the alter operation is complete.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.commands.AlterTableAddColumns;
import com.datastax.astra.client.tables.definition.rows.Row;

public class AlterTableAddColumn {

 public static void main(String[] args) {
  // Database db = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();
  Table<Row> myTable1 = db.getTable("games");

  // Add A Columns
  AlterTableAddColumns add = new AlterTableAddColumns()
          .addColumnBoolean("tie_break")
          .addColumnText("venue");
  myTable1.alter(add);

 }

}

Add a new column:

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 '{
  "alterTable": {
    "operation": {
      "add": {
        "columns": {
          "NEW_COLUMN_NAME": "DATA_TYPE"
        }
      }
    }
  }
}' | jq

Parameters:

Name Type Summary

alterTable

command

The Data API command to modify the configuration of a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to modify the table.

operation.add

object

Specifies that you want to add a column to the table.

operation.add.columns

object

Define columns to add to the table.

The format is the same as when you define columns in createTable.

Returns:

Table<NewBean> - The table object re-casted as its new type once the alter operation is complete.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.commands.AlterTableAddColumns;
import com.datastax.astra.client.tables.commands.AlterTableDropColumns;
import com.datastax.astra.client.tables.definition.rows.Row;

public class AlterTableDropColumn {

 public static void main(String[] args) {
  // Database db = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();
  Table<Row> myTable1 = db.getTable("games");

  // Add A Columns
  AlterTableDropColumns dropColumn = new AlterTableDropColumns("tie_break");
  myTable1.alter(dropColumn);

 }

}

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 '{
  "alterTable": {
    "operation": {
      "add": {
        "columns": {
          "deans_list": "boolean"
        }
      }
    }
  }
}' | jq

Drop columns

Remove one or more columns from an existing table.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Drop a column from a table:

new_table = my_table.alter(AlterTableDropColumns(
    columns=["tie_break"],
))

Drop columns from a table and use the return value for strict control over types:

new_table: Table[MyCustomNarrowDictType] = my_table.alter(
    AlterTableDropColumns(
        columns=["tie_break", "venue"],
    ),
    row_type=MyCustomNarrowDictType,
)

Parameters:

Name Type Summary

operation

AlterTableDropColumns | dict

An instance of AlterTableDropColumns detailing the names of the columns to be removed. This is the same method used to drop columns and add/drop vectorize integrations. This parameter selects which alter operation to performe based on the object provided. Passing a regular dictionary such as {"drop": {"columns": …​}} achieves the same effect.

row_type

type

This parameter acts a formal specifier for the type checker. If omitted, the resulting Table is implicitly a Table[dict[str, Any]]. If provided, it must match the type hint specified in the assignment. For more information, see Typing support.

table_admin_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:

Table - A new Table instance formally representing the table after the schema change. While you can continue working with the original class instance, stricter typing is achieved by providing a type hint to the new shape of the rows in the table, with a proper subclass of TypedDict, and using the return value of this method immediately.

Example response

The following example repsonse is reformatted for clarity:

Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

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()
    ),
)

from astrapy.info import (
    AlterTableAddColumns,
    ColumnType,
    TableScalarColumnTypeDescriptor,
)

# Add a column
new_table = my_table.alter(
    AlterTableAddColumns(
        columns={
            "tie_break": TableScalarColumnTypeDescriptor(
                column_type=ColumnType.BOOLEAN,
            ),
        },
    ),
)

# Drop a column
from astrapy.info import AlterTableDropColumns

new_table = my_table.alter(AlterTableDropColumns(
    columns=["tie_break"],
))

For more information, see the Client reference.

Drop columns from the table and update the Table type:

const newTable = await table.alter<NewSchema>({
  operation: {
    drop: {
      columns: ['tieBreak', 'venue'],
    },
  },
});

Parameters:

Name Type Summary

operation.drop

DropColumnOperation

Defines an operation to alter a table by dropping one or more columns.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Options (DropColumnOperation):

Name Type Summary

columns

Cols<Schema>[]

The names of the columns to drop from the table.

Returns:

Promise<Table<NewSchema>> - A promise which resolves to the table object recast as its new type after the alter operation is complete.

Don’t use the orginal table’s type. Continuing to use the original table’s type causes the type of the table to desync from the table’s actual schema.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema } 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.
// For information about table definition and data types, 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;

// Infer the table type from the table definition.
// For information about table typing, see the documentation for create table.
type TableSchema = InferTableSchema<typeof TableDefinition>;

// The following script demonstrates all alter operations: add, drop, addVectorize, dropVectorize.
// This example also inserts rows to demonstrate the goal and outcome of each alter operation.
// You can only run one alter operation at a time, but you can have multiple operations in the same script.
(async function () {
  // Create a table or error if a 'games' table already exists.
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Represents the new schema of the table after the alter to add columns
  type NewSchema = TableSchema & {
    tieBreak: boolean;
    venue: string;
  }

  // @ts-expect-error
  // Try to insert data into nonexistent columns.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  // Columns are defined in the same way that you define them in createTable, including name, type, and other properties.
  const altered = await table.alter<NewSchema>({
    operation: {
      add: {
        columns: {
          tieBreak: 'boolean',
          venue: 'text',
        },
      },
    },
  });

  // Attempt to insert the rows again.
  // This should succeed now that all columns exist in the table.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' });
  console.log('inserted', inserted.insertedId);

  // Represents the new schema of the table after the alter to drop columns
  type NewSchema = Omit<TableSchema, 'tieBreak' | 'venue'>

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  const altered = await table.alter<NewSchema>({
    operation: {
      drop: {
        columns: ['tieBreak', 'venue'],
      },
    },
  });

  // @ts-expect-error
  // Try to insert data into the removed columns.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // @ts-expect-error
  // Try to use vectorize on a vector column that doesn't have a vectorize integration.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Add the OpenAI embedding provider integration to the vector column.
  const altered = await table.alter({
    operation: {
      addVectorize: {
        columns: {
          mVector: {
            provider: 'openai',
            modelName: 'text-embedding-3-small',
            authentication: {
              providerKey: 'ASTRA_KMS_API_KEY_NAME',
            },
          },
        },
      },
    },
  });

  // Attempt to insert the row again.
  // This should succeed now that the vector column has a vectorize integration.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' });
  console.log('inserted', inserted.insertedId);

  // Remove vectorize from the specified vector column
  const altered = await table.alter({
    operation: {
      dropVectorize: {
        columns: ['mVector'],
      },
    },
  });

  // @ts-expect-error
  // Try to use vectorize on the vector column that no longer has a vectorize integration.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();

Expand the preceding Full script example for the definition of NewSchema that is used in the following truncated example:

// Provide the new type of the table as it would be after the alter.
// Note that this just returns the same Table object, but re-casted as the proper type.
const altered = await table.alter<NewSchema>({
  operation: {
    drop: {
      columns: ['tieBreak', 'venue'],
    },
  },
});

// @ts-expect-error
// Try to insert data into the removed columns.
// This should error both statically and at runtime.
await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
  .catch(e => console.error(e.message));

For more information, see the Client reference.

Drop a column from a table:

myTable.alter(new AlterTableDropColumns("tie_break"));

Drop columns from a table, use the return value for strict control over types, and specialize with options:

AlterTableDropColumns alterOperation = new AlterTableDropColumns()
 .columns("tie_break", "venue");
AlterTableOptions  alterOptions = new AlterTableOptions()
 .timeout(10000L);
Table<Game> myUpdatedTable = myTable
  .alter(alterOperation, alterOptions, Game.class);

Parameters:

Name Type Summary

operation

AlterTableDropColumns

Defines an operation to alter a table by dropping one or more columns.

options

AlterTableOptions

Specialization of the operation, such as timeout.

rowClass

Class<?>

Optional new type for the row object. If not provided, the default is Row, which is like a Map object.

Returns:

Table<NewBean> - The table object recast as its new type after the alter operation is complete.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.commands.AlterTableAddColumns;
import com.datastax.astra.client.tables.commands.AlterTableDropColumns;
import com.datastax.astra.client.tables.definition.rows.Row;

public class AlterTableDropColumn {

 public static void main(String[] args) {
  // Database db = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();
  Table<Row> myTable1 = db.getTable("games");

  // Add A Columns
  AlterTableDropColumns dropColumn = new AlterTableDropColumns("tie_break");
  myTable1.alter(dropColumn);

 }

}

Drop a column:

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 '{
  "alterTable": {
    "operation": {
      "drop": {
        "columns": [ "COLUMN_NAME", "COLUMN_NAME" ]
      }
    }
  }
}' | jq

Parameters:

Name Type Summary

alterTable

command

The Data API command to modify the configuration of a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to modify the table.

operation.drop

object

Specifies that you want to remove a column from the table.

operation.drop.columns

array

The names of the columns to remove from the table.

Returns:

A successful request returns 200 OK.

Example response
{
  "status": {
    "ok": 1
  }
}

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 '{
  "alterTable": {
    "operation": {
      "drop": {
        "columns": [ "deans_list" ]
      }
    }
  }
}' | jq

Add vectorize to columns

To automatically generate embeddings with vectorize, you configure an embedding provider integration on a vector column. Astra DB stores the automatically-generated embeddings in this column.

This operation adds an embedding provider integration to an existing vector column. You can modify multiple vector columns in a single request.

For information about inserting vector data and automatically generating embeddings in tables, see Vector type and Insert rows reference.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Add vectorize to a column:

my_table.alter(
    AlterTableAddVectorize(
        columns={
            "m_vector": VectorServiceOptions(
                provider="openai",
                model_name="text-embedding-3-small",
                authentication={
                    "providerKey": "ASTRA_KMS_API_KEY_NAME",
                },
            ),
        },
    ),
)

Parameters:

Name Type Summary

operation

AlterTableAddVectorize | dict

An instance of AlterTableAddVectorize detailing the name and vectorize options for each column to modify. This is the same method used to add/drop columns and drop vectorize information. This parameter selects the update operation to perform based on the object provided. Passing a regular dictionary such as {"addVectorize": {"columns": …​}} achieves the same effect.

row_type

type

DataStax does not recommend using row_type with AlterTableAddVectorize. Likewise, do not assign the return value of this method to any variable. Continue using the original Table instance after this operation.

table_admin_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:

Table - A new table object that is only useful for type-hints purposes. Do not use the new Table instance. Instead, continue to use the original Table instance for this table.

Example response

The following example response is reformatted for clarity:

Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

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()
    ),
)

from astrapy.info import AlterTableAddVectorize, VectorServiceOptions

new_table = my_table.alter(
    AlterTableAddVectorize(
        columns={
            "m_vector": VectorServiceOptions(
                provider="openai",
                model_name="text-embedding-3-small",
                authentication={
                    "providerKey": "ASTRA_KMS_API_KEY_NAME",
                },
            ),
        },
    ),
)

For more information, see the Client reference.

Add vectorize to a column:

const newTable = await table.alter({
  operation: {
    addVectorize: {
      columns: {
        mVector: {
          provider: 'openai',
          modelName: 'text-embedding-3-small',
          authentication: {
            providerKey: 'ASTRA_KMS_API_KEY_NAME',
          },
        },
      },
    },
  },
});

Parameters:

Name Type Summary

operation.addVectorize

AddVectorizeOperation

Defines an operation to alter a table by adding a vectorize integration to one or more vector columns.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Options (AddVectorizeOperation):

Name Type Summary

columns

Record<Cols<Schema>, VectorizeServiceOptions>

Specify the names of the vector columns to alter and the vectorize options for each column. The definition is the same as when you define columns in createTable. For more information, see Define a column to automatically generate vector embeddings.

Returns:

Promise<Table<Schema>> - A promise which resolves to the Table object once the alter operation is complete.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema } 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.
// For information about table definition and data types, 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;

// Infer the table type from the table definition.
// For information about table typing, see the documentation for create table.
type TableSchema = InferTableSchema<typeof TableDefinition>;

// The following script demonstrates all alter operations: add, drop, addVectorize, dropVectorize.
// This example also inserts rows to demonstrate the goal and outcome of each alter operation.
// You can only run one alter operation at a time, but you can have multiple operations in the same script.
(async function () {
  // Create a table or error if a 'games' table already exists.
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Represents the new schema of the table after the alter to add columns
  type NewSchema = TableSchema & {
    tieBreak: boolean;
    venue: string;
  }

  // @ts-expect-error
  // Try to insert data into nonexistent columns.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  // Columns are defined in the same way that you define them in createTable, including name, type, and other properties.
  const altered = await table.alter<NewSchema>({
    operation: {
      add: {
        columns: {
          tieBreak: 'boolean',
          venue: 'text',
        },
      },
    },
  });

  // Attempt to insert the rows again.
  // This should succeed now that all columns exist in the table.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' });
  console.log('inserted', inserted.insertedId);

  // Represents the new schema of the table after the alter to drop columns
  type NewSchema = Omit<TableSchema, 'tieBreak' | 'venue'>

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  const altered = await table.alter<NewSchema>({
    operation: {
      drop: {
        columns: ['tieBreak', 'venue'],
      },
    },
  });

  // @ts-expect-error
  // Try to insert data into the removed columns.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // @ts-expect-error
  // Try to use vectorize on a vector column that doesn't have a vectorize integration.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Add the OpenAI embedding provider integration to the vector column.
  const altered = await table.alter({
    operation: {
      addVectorize: {
        columns: {
          mVector: {
            provider: 'openai',
            modelName: 'text-embedding-3-small',
            authentication: {
              providerKey: 'ASTRA_KMS_API_KEY_NAME',
            },
          },
        },
      },
    },
  });

  // Attempt to insert the row again.
  // This should succeed now that the vector column has a vectorize integration.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' });
  console.log('inserted', inserted.insertedId);

  // Remove vectorize from the specified vector column
  const altered = await table.alter({
    operation: {
      dropVectorize: {
        columns: ['mVector'],
      },
    },
  });

  // @ts-expect-error
  // Try to use vectorize on the vector column that no longer has a vectorize integration.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();
// @ts-expect-error
// Try to use vectorize on a vector column that doesn't have a vectorize integration.
// This should error both statically and at runtime.
await table.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
  .catch(e => console.error(e.message));

// Add the OpenAI embedding provider integration to the vector column.
const altered = await table.alter({
  operation: {
    addVectorize: {
      columns: {
        mVector: {
          provider: 'openai',
          modelName: 'text-embedding-3-small',
          authentication: {
            providerKey: 'ASTRA_KMS_API_KEY_NAME',
          },
        },
      },
    },
  },
});

// Attempt to insert the row again.
// This should succeed now that the vector column has a vectorize integration.
const inserted = await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' });
console.log('inserted', inserted.insertedId);

For more information, see the Client reference.

Add vectorize to a column:

VectorServiceOptions options = new VectorServiceOptions()
   .modelName("text-embedding-3-small")
   .provider("openai")
   .authentication(Map.of("providerKey", "ASTRA_KMS_API_KEY_NAME"));
AlterTableAddVectorize addVectorize =
 new AlterTableAddVectorize()
  .columns(Map.of("m_vector", options));

myTable1.alter(addVectorize);

Parameters:

Name Type Summary

operation

AlterTableAddVectorize

Defines an operation to alter a table by adding a vectorize integration to one or more vector columns.

options

AlterTableOptions

Specialization of the operation, such as timeout.

rowClass

Class<?>

Optional new type for the row object. If not provided, the default is Row, Row is close to an Map object

Returns:

Table<T> - An instance for interacting with the current table where T represents a Row. Alter operations can change the row definition in a table. However, when adding or dropping vectorize integrations, the pre-existing Table object should remain largely unchanged.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.core.vectorize.VectorServiceOptions;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.commands.AlterTableAddVectorize;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.util.Map;

public class AlterTableAddVectorizes {

 public static void main(String[] args) {
  // Database db = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();
  Table<Row> myTable1 = db.getTable("games");
  AlterTableAddVectorize addVectorize =
   new AlterTableAddVectorize().columns(
    Map.of("m_vector", new VectorServiceOptions()
     .modelName("text-embedding-3-small")
     .provider("openai").authentication(
      Map.of("providerKey", "ASTRA_KMS_API_KEY_NAME")
   ))
  );
  myTable1.alter(addVectorize);
 }

}

Add a vectorize embedding provider integration to an existing vector column:

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 '{
  "alterTable": {
    "operation": {
      "addVectorize": {
        "columns": {
          "VECTOR_COLUMN_NAME": {
            "type": "vector",
            "dimension": NUM_DIMENSIONS,
            "service": {
              "provider": "EMBEDDINGS_PROVIDER_NAME",
              "modelName": "MODEL_NAME"
            }
          }
        }
      }
    }
  }
}' | jq

Parameters:

Name Type Summary

alterTable

command

The Data API command to modify the configuration of a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to modify the table.

operation.addVectorize

object

Specifies that you want to add a vectorize integration to an existing vector column.

operation.addVectorize.columns

object

Provide the name of the target vector column, the dimension, and the vectorize service options.

service is an object containing provider, modelName, and other parameters for the embedding provider integration. Most integrations require authentication in service.authentication.providerKey or through an x-embedding-api-key header. For more information, see Vector type.

Returns:

A successful request returns 200 OK.

Example response
{
  "status": {
    "ok": 1
  }
}

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 '{
  "alterTable": {
    "operation": {
      "addVectorize": {
        "columns": {
          "embedding": {
            "type": "vector",
            "dimension": 1024,
            "service": {
              "provider": "mistral",
              "modelName": "mistral-embed",
              "authentication": {
                "providerKey": "mistral-api-key"
              }
            }
          }
        }
      }
    }
  }
}' | jq

Remove vectorize from columns

Remove a vectorize embedding provider integration from a vector column. You can modify multiple vector columns in a single request.

This operation doesn’t remove the embeddings stored in the column. The column becomes a normal vector column with no capability for automatic embedding generation.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Remove vectorize from a column:

new_table = my_table.alter(
    AlterTableDropVectorize(columns=["m_vector"]),
)

Parameters:

Name Type Summary

operation

AlterTableDropVectorize | dict

An instance of AlterTableDropVectorize detailing the names of each column from which you want to remove a vectorize integration. This is the same method used to add/drop columns and add vectorize information. This parameter selects the update operation to perform based on the object provided. Passing a regular dictionary such as {"dropVectorizeadd": {"columns": …​}} achieves the same effect.

row_type

type

DataStax does not recommend using row_type with AlterTableAddVectorize. Likewise, do not assign the return value of this method to any variable. Continue using the original Table instance after this operation.

table_admin_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:

Table - A new table object that is only useful for type-hints purposes. Do not use the new Table instance. Instead, continue to use the original Table instance for this table.

Example response

The following example response is reformatted for clarity:

Table(
  name="COLLECTION_NAME",
  keyspace="default_keyspace",
  database.api_endpoint="ASTRA_DB_API_ENDPOINT",
  api_options=FullAPIOptions(
    token=StaticTokenProvider(APPLICATION_TOKEN),
    ...
  ),
  ...
)

Example:

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()
    ),
)

from astrapy.info import AlterTableAddVectorize, VectorServiceOptions

new_table = my_table.alter(
    AlterTableAddVectorize(
        columns={
            "m_vector": VectorServiceOptions(
                provider="openai",
                model_name="text-embedding-3-small",
                authentication={
                    "providerKey": "ASTRA_KMS_API_KEY_NAME",
                },
            ),
        },
    ),
)

from astrapy.info import AlterTableDropVectorize

# Drop vectorize from a (vector) column
new_table = my_table.alter(
    AlterTableDropVectorize(columns=["m_vector"]),
)

For more information, see the Client reference.

Remove vectorize from a table column:

const newTable = await table.alter({
  operation: {
    dropVectorize: {
      columns: ['mVector'],
    },
  },
});

Parameters:

Name Type Summary

operation.dropVectorize

DropVectorizeOperation

Defines an operation to alter a table by dropping a vectorize integration from one or more vector columns.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Options (DropVectorizeOperation):

Name Type Summary

columns

Cols<Schema>[]

The names of the columns from which to remove vectorize information.

Returns:

Promise<Table<Schema>> - A promise which resolves to the Table object after the alter operation is complete.

Example:

Full script
import { CreateTableDefinition, DataAPIClient, InferTablePrimaryKey, InferTableSchema } 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.
// For information about table definition and data types, 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;

// Infer the table type from the table definition.
// For information about table typing, see the documentation for create table.
type TableSchema = InferTableSchema<typeof TableDefinition>;

// The following script demonstrates all alter operations: add, drop, addVectorize, dropVectorize.
// This example also inserts rows to demonstrate the goal and outcome of each alter operation.
// You can only run one alter operation at a time, but you can have multiple operations in the same script.
(async function () {
  // Create a table or error if a 'games' table already exists.
  const table = await db.createTable<TableSchema>('games', { definition: TableDefinition });

  // Represents the new schema of the table after the alter to add columns
  type NewSchema = TableSchema & {
    tieBreak: boolean;
    venue: string;
  }

  // @ts-expect-error
  // Try to insert data into nonexistent columns.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  // Columns are defined in the same way that you define them in createTable, including name, type, and other properties.
  const altered = await table.alter<NewSchema>({
    operation: {
      add: {
        columns: {
          tieBreak: 'boolean',
          venue: 'text',
        },
      },
    },
  });

  // Attempt to insert the rows again.
  // This should succeed now that all columns exist in the table.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' });
  console.log('inserted', inserted.insertedId);

  // Represents the new schema of the table after the alter to drop columns
  type NewSchema = Omit<TableSchema, 'tieBreak' | 'venue'>

  // Provide the new type of the table as it would be after the alter.
  // Note that this just returns the same Table object, but re-casted as the proper type.
  const altered = await table.alter<NewSchema>({
    operation: {
      drop: {
        columns: ['tieBreak', 'venue'],
      },
    },
  });

  // @ts-expect-error
  // Try to insert data into the removed columns.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, tieBreak: true, venue: 'Thunderdome' })
    .catch(e => console.error(e.message));

  // @ts-expect-error
  // Try to use vectorize on a vector column that doesn't have a vectorize integration.
  // This should error both statically and at runtime.
  await table.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Add the OpenAI embedding provider integration to the vector column.
  const altered = await table.alter({
    operation: {
      addVectorize: {
        columns: {
          mVector: {
            provider: 'openai',
            modelName: 'text-embedding-3-small',
            authentication: {
              providerKey: 'ASTRA_KMS_API_KEY_NAME',
            },
          },
        },
      },
    },
  });

  // Attempt to insert the row again.
  // This should succeed now that the vector column has a vectorize integration.
  const inserted = await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' });
  console.log('inserted', inserted.insertedId);

  // Remove vectorize from the specified vector column
  const altered = await table.alter({
    operation: {
      dropVectorize: {
        columns: ['mVector'],
      },
    },
  });

  // @ts-expect-error
  // Try to use vectorize on the vector column that no longer has a vectorize integration.
  // This should error both statically and at runtime.
  await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
    .catch(e => console.error(e.message));

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();
// Remove vectorize from the specified vector column
const altered = await table.alter({
  operation: {
    dropVectorize: {
      columns: ['mVector'],
    },
  },
});

// @ts-expect-error
// Try to use vectorize on the vector column that no longer has a vectorize integration.
// This should error both statically and at runtime.
await altered.insertOne({ matchId: '1', round: 1, mVector: 'The ☀️, The 🌙, The 🌟' })
  .catch(e => console.error(e.message));

For more information, see the Client reference.

Remove vectorize from a column:

AlterTableDropVectorize dropVectorize =
  new AlterTableDropVectorize("m_vector");
myTable1.alter(dropVectorize);

Parameters:

Name Type Summary

operation

AlterTableDropVectorize

Defines an operation to alter a table by dropping a vectorize integration from one or more vector columns.

options

AlterTableOptions

Specialization of the operation, including timeout.

rowClass

Class<?>

Optional new type for the row object. If not provided, the default is Row, Row is close to an Map object

Returns:

Table<T> - An instance for interacting with the current table where T represents a Row. Alter operations can change the row definition in a table. However, when adding or dropping vectorize integrations, the pre-existing Table object should remain largely unchanged.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.commands.AlterTableDropColumns;
import com.datastax.astra.client.tables.commands.AlterTableDropVectorize;
import com.datastax.astra.client.tables.definition.rows.Row;

public class AlterTableDropVectorizes {

 public static void main(String[] args) {
  // Database db = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();
  Table<Row> myTable1 = db.getTable("games");

  // Add A Columns
  AlterTableDropVectorize dropVectorize = new AlterTableDropVectorize("m_vector");
  myTable1.alter(dropVectorize);

 }

}

Remove an embedding provider integration from a vector column:

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 '{
  "alterTable": {
    "operation": {
      "dropVectorize": {
        "columns": [ "VECTOR_COLUMN_NAME" ]
      }
    }
  }
}' | jq

Parameters:

Name Type Summary

alterTable

command

The Data API command to modify the configuration of a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to modify the table.

operation.dropVectorize

object

Specify that you want to remove a vectorize integration from a vector column.

operation.dropVectorize.columns

array

The name of the vector column from which you want to remove the embedding provider integration.

Returns:

A successful request returns 200 OK.

Example response
{
  "status": {
    "ok": 1
  }
}

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 '{
  "alterTable": {
    "operation": {
      "dropVectorize": {
        "columns": [ "embedding" ]
      }
    }
  }
}' | jq

List table metadata

Get information about the tables in a specific keyspace.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Get information about the tables in the database’s working keyspace:

database.list_tables()

Get information about tables in a specific keyspace:

database.list_tables(keyspace="KEYSPACE_NAME")

Parameters:

Name Type Summary

keyspace

Optional[str]

The keyspace to be inspected. If not specified, the database’s working keyspace is used.

table_admin_timeout_ms

Optional[int]

A timeout, in milliseconds, for the underlying HTTP request. If not provided, the Database setting is used. This parameter is aliased as request_timeout_ms and timeout_ms for convenience.

Returns:

List[ListTableDescriptor] - A list of ListTableDescriptor objects in no particular order.

Example response

The following example response is reformatted for clarity:

[
  BaseTableDescriptor(
    name='fighters',
    definition=BaseTableDefinition(
      columns=[fighter_id,age,name,nationality,skill_levels],
      primary_key=TablePrimaryKeyDescriptor[(fighter_id)]
    ),
    raw_descriptor=...
  ),
  BaseTableDescriptor(
    name='games',
    definition=BaseTableDefinition(
      columns=[match_id,round,fighters,m_vector,score,when,winner],
      primary_key=TablePrimaryKeyDescriptor[(match_id)round:a]
    ),
    raw_descriptor=...
  )
]

Example:

from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

tables = my_database.list_tables()
tables
# [BaseTableDescriptor(name='fighters', definition=BaseTableDefinition(...
tables[1].name
# 'games'
tables[1].definition.columns
# {'match_id': TableScalarColumnTypeDescriptor(ColumnType.TEXT),...
tables[1].definition.columns['score']
# TableScalarColumnTypeDescriptor(ColumnType.INT)
tables[1].definition.primary_key.partition_by
# ['match_id']
tables[1].definition.primary_key.partition_sort
# {'round': 1}

For more information, see the Client reference.

Get information about the tables in the database’s working keyspace:

await db.listTables();

Get information about tables in a specified keyspace in the database:

await db.listTables({ keyspace: 'KEYSPACE' });

Parameters:

Name Type Summary

options?

ListTablesOptions

The options for this operation.

Options (ListTablesOptions):

Name Type Summary

nameOnly?

boolean

If false or undefined, the response includes table names and metadata. If true, the response includes only table names.

keyspace?

string

The keyspace to be inspected. If not specified, the database’s working keyspace is used.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Returns:

Promise<FullTableInfo[]> - A promise that resolves to an array of table descriptor objects in no particular order.

Example response
[
  {
    name: 'games',
    definition: {
      columns: {
        matchId: { type: 'text' },
        round: { type: 'tinyint' },
        fighters: { type: 'set', valueType: 'uuid' },
        mVector: { type: 'vector', dimension: 3 },
        score: { type: 'int' },
        when: { type: 'timestamp' },
        winner: { type: 'text' }
      },
      primaryKey: {
        partitionBy: [ 'matchId' ],
        partitionSort: { round: 1 }
      }
    }
  }
]

Example:

import { CreateTableDefinition, DataAPIClient, SomeRow } 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.
// For information about table definition and data types, 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;

(async function () {
  // Create an untyped table if a 'games' table doesn't already exist.
  await db.createTable<SomeRow>('games', { definition: TableDefinition, ifNotExists: true });

  // Get detailed information about the table.
  // Returns information like [{ name: 'games', definition: { ... } }, ...]
  await db.listTables().then(console.log);

  // Get table names only.
  // Returns information like ['games', ...]
  await db.listTables({ nameOnly: true }).then(console.log);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();

For more information, see the Client reference.

Get information about tables in the database’s working keyspace:

List<TableDescriptor> tableList = db.listTables();

Get information about tables in a specific keyspace and apply a custom timeout:

ListTablesOptions options = new ListTablesOptions()
  .keyspace("KEYSPACE_NAME")
  .timeout(Duration.ofSeconds(5));

List<TableDescriptor> tableList2 = database
  .listTables(options);

Parameters:

Name Type Summary

options

ListTablesOptions

Specialization of the operation, including timeout and keyspace.

Returns:

List<TableDescriptor> - A list of TableDescriptor objects in no particular order.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Game;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.TableOptions;
import com.datastax.astra.client.tables.commands.options.ListTablesOptions;
import com.datastax.astra.client.tables.definition.TableDefinition;
import com.datastax.astra.client.tables.definition.TableDescriptor;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.time.Duration;
import java.util.List;
import java.util.Map;

public class ListTables {

 public static void main(String[] args) {
  // Database astraDb =  new DataAPIClient(token).getDatabase(endpoint);
  Database db =
    DataAPIClients.localDbWithDefaultKeyspace();

  // Default
  List<TableDescriptor> tableList = db.listTables();

  // Options
  db.getDatabaseAdmin().createKeyspace("ks2");
  ListTablesOptions options = new ListTablesOptions()
          .keyspace("ks2")
          .timeout(Duration.ofSeconds(5));
  List<TableDescriptor> tableList2 = db.listTables(options);
  Table<Row> ts = db.getTable("table_simple", new TableOptions().keyspace("ks2"));
  // Expecting an error as table does not exist in ks2
 }
}

To get table metadata, use listTables with "explain": true:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "listTables": {
    "options": {
      "explain": true
    }
  }
}' | jq

Parameters:

Name Type Summary

listTables

command

The Data API command to get a list of tables in a keyspace in a Serverless (Vector) database.

options.explain

boolean

Whether the response includes table metadata in addition to table names.

Returns:

A successful response returns a tables array that contains an object for each table. If "explain": true, then each table object contains the table schema, including the table name, column definitions, and primary key.

Example response
{
  "status": {
    "tables": [
      {
        "name": "customers",
        "definition": {
          "columns": {
            "order_date": {
              "type": "timestamp"
            },
            "preferences": {
              "type": "map",
              "keyType": "text",
              "valueType": "text"
            },
            "is_active": {
              "type": "boolean"
            },
            "user_id": {
              "type": "uuid"
            },
            "name": {
              "type": "text"
            },
            "login_attempts": {
              "type": "set",
              "valueType": "int"
            },
            "photo": {
              "type": "blob"
            },
            "salary": {
              "type": "decimal"
            },
            "order_id": {
              "type": "uuid"
            },
            "age": {
              "type": "int"
            },
            "tags": {
              "type": "list",
              "valueType": "text"
            }
          },
          "primaryKey": {
            "partitionBy": [
              "user_id"
            ],
            "partitionSort": {
              "order_id": 1,
              "order_date": -1
            }
          }
        }
      }
    ]
  }
}

List table names

Get the names of the tables in a specific keyspace as a list of strings.

For the clients, unless otherwise specified, this implementation refers to the tables in the database’s working keyspace.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Get the names of tables in the database’s working keyspace:

database.list_table_names()

Get the names of tables in a specific keyspace in the database:

database.list_table_names(keyspace="KEYSPACE_NAME")

Parameters:

Name Type Summary

keyspace

Optional[str]

The keyspace to be inspected. If not specified, the database’s working keyspace is used.

table_admin_timeout_ms

Optional[int]

A timeout, in milliseconds, for the underlying HTTP request. If not provided, the Database setting is used. This parameter is aliased as request_timeout_ms and timeout_ms for convenience.

Returns:

List[str] - A list of the table names in no particular order.

Example response
['fighters', 'games']

Example:

from astrapy import DataAPIClient
client = DataAPIClient("TOKEN")
database = client.get_database("API_ENDPOINT")

database.list_table_names()
# ['fighters', 'games']

For more information, see the Client reference.

Get the names of tables in the database’s working keyspace:

await db.listTables({ nameOnly: true });

Get the names of tables in a specific keyspace in the database:

await db.listTables({ nameOnly: true, keyspace: 'KEYSPACE' });

Parameters:

Name Type Summary

options

ListTablesOptions

The options for this operation.

Options (ListTablesOptions):

Name Type Summary

nameOnly?

boolean

If false or undefined, the response includes table names and metadata. If true, the response includes only table names.

keyspace?

string

The keyspace to be inspected. If not specified, the database’s working keyspace is used.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Returns:

Promise<string[]> - A promise that resolves to an array of all the table names in the keyspace.

Example response
['games']

Example:

import { CreateTableDefinition, DataAPIClient, SomeRow } 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.
// For information about table definition and data types, 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;

(async function () {
  // Create an untyped table if a 'games' table doesn't already exist.
  await db.createTable<SomeRow>('games', { definition: TableDefinition, ifNotExists: true });

  // Get detailed information about the table.
  // Returns information like [{ name: 'games', definition: { ... } }, ...]
  await db.listTables().then(console.log);

  // Get table names only.
  // Returns information like ['games', ...]
  await db.listTables({ nameOnly: true }).then(console.log);

  // Uncomment the following line to drop the table and any related indexes.
  // await table.drop();
})();

For more information, see the Client reference.

Get the name of tables in the database’s working keyspace:

List<String> tableNames = db.listTableNames();

Get the names of tables in a specific keyspace in the database and pass a custom timeout:

ListTablesOptions options = new ListTablesOptions()
  .keyspace("ks2")
  .timeout(Duration.ofSeconds(5));
List<String> tableList2 = database
  .listTableNames(options);

Parameters:

Name Type Summary

options

ListTablesOptions

Specialization of the operation, including timeout and keyspace.

Returns:

List<String> - A list of String, each representing a table name.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.TableOptions;
import com.datastax.astra.client.tables.commands.options.ListTablesOptions;
import com.datastax.astra.client.tables.definition.TableDescriptor;
import com.datastax.astra.client.tables.definition.rows.Row;

import java.time.Duration;
import java.util.List;

public class ListTablesNames {

 public static void main(String[] args) {
  // Database astraDb =  new DataAPIClient(token).getDatabase(endpoint);
  Database db =
    DataAPIClients.localDbWithDefaultKeyspace();

  // Default
  List<String> tableNames = db.listTableNames();

  // Options
  db.getDatabaseAdmin().createKeyspace("ks2");
  ListTablesOptions options = new ListTablesOptions()
          .keyspace("ks2")
          .timeout(Duration.ofSeconds(5));
  List<String> tableList2 = db.listTableNames(options);

 }
}
curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "listTables": {
    "options": {
      "explain": false
    }
  }
}' | jq

Parameters:

Name Type Summary

listTables

command

The Data API command to get a list of tables in a keyspace in a Serverless (Vector) database.

options.explain

boolean

If true, the response includes table names and metadata. If false or unset, the response includes only table names.

Returns:

If "explain": false, a successful response returns a array of table names.

Example response
{
  "status": {
    "tables": [
      "table_name_1",
      "table_name_2"
    ]
  }
}

Drop a table

Delete a table from a database, including all associated indexes and data stored in the table.

Attempting to use the table object after dropping the table returns an API error because it references a non-existent table.

  • Python

  • TypeScript

  • Java

  • curl

For more information, see the Client reference.

Drop a table by name:

database.drop_table("fighters")

Drop a table through a Table object:

my_table.drop()

Drop a table passing a Table to a Database:

database.drop_table(my_table)

Parameters:

Name Type Summary

name_or_table

str | Table

Either the name of a table or a Table instance.

if_exists

bool

If True, and the specified table doesn’t exist in the keyspace, then the command succeeds and silently does nothing. In this case, no actual table deletion occurs.

If False (default), an error occurs if a table with the specified name does not exist in the keyspace.

table_admin_timeout_ms

int

A timeout, in milliseconds, for the underlying schema-changing HTTP request. If not provided, the Database defaults apply. This parameter is aliased as request_timeout_ms and timeout_ms for convenience.

Example:

database.list_table_names()
# ['fighters', 'games']
database.drop_table("fighters")
database.list_table_names()
# ['games']
# not erroring because of if_exists:
database.drop_table("fighters", if_exists=True)

For more information, see the Client reference.

Drop a table by name in the database’s working keyspace:

await db.dropTable('TABLE_NAME');

Drop a table by name in a specific keyspace:

await db.dropTable('TABLE_NAME', { keyspace: 'KEYSPACE' });

Drop a table through a Table object:

await table.drop();

Parameters:

Name Type Summary

name

string

The name of the table to drop, if dropping through a Db instance.

option?

DropTableOptions

The options for this operation

Options (DropTableOptions):

Name Type Summary

ifExists?

boolean

If true, and the specified table doesn’t exist in the keyspace, then the command succeeds and silently does nothing. In this case, no actual table deletion occurs.

If false (default), an error occurs if a table with the specified name does not exist in the keyspace.

keyspace?

string

If dropping through a Db instance, specify the keyspace containing the table that you want to drop. If unspecified, the database’s working keyspace is used.

timeout?

number | TimeoutDescriptor

The client-side timeout for this operation.

Returns:

Promise<void> - A promise that resolves when the operation is complete.

Example:

import { CreateTableDefinition, DataAPIClient, SomeRow } 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.
// For information about table definition and data types, 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;

(async function () {
  // Create an untyped table or error if a 'games' table already exists.
  const table = await db.createTable<SomeRow>('games', { definition: TableDefinition });

  // Drop a table from a database's working keyspace without checking if the table exists.
  // If there is no match, the command succeeds but does nothing.
  // If there is a match, the named table is deleted.
  await db.dropTable(table.name);

  // Use a Table object to run dropTable without checking if the table exists.
  await table.drop();

  // Use a Table object to drop a table only if the table exists.
  // Errors if there is no match.
  await table.drop({ ifExists: true });

})();

For more information, see the Client reference.

Drop a table by name in the database’s working keyspace:

database.dropTable("fighters");

Drop a table through a Table object:

myTable.drop();

Drop a table through a database instance with options:

DropTableOptions options = new DropTableOptions()
 .ifExists(false)
 .timeout(ofSeconds(5));
database.dropTable("games", options);

Parameters:

Name Type Summary

name

str

The name of the table to drop, if dropping through a database instance.

options

DropTableOptions

Specialization of the operation:

  • ifExists(): If true, and the specified table doesn’t exist in the keyspace, then the command succeeds and silently does nothing. In this case, no actual table deletion occurs.

    If false (default), an error occurs if a table with the specified name does not exist in the keyspace.

  • keyspace() If dropping through a database instance, specify the keyspace containing the table that you want to drop. If unspecified, the database’s working keyspace is used.

  • timeout: The client-side timeout for this operation.

Example:

package com.datastax.astra.client.database;

import com.datastax.astra.client.DataAPIClients;
import com.datastax.astra.client.core.auth.EmbeddingAPIKeyHeaderProvider;
import com.datastax.astra.client.databases.Database;
import com.datastax.astra.client.tables.Game;
import com.datastax.astra.client.tables.Table;
import com.datastax.astra.client.tables.TableOptions;
import com.datastax.astra.client.tables.commands.options.CreateTableOptions;
import com.datastax.astra.client.tables.commands.options.DropTableOptions;
import com.datastax.astra.client.tables.definition.TableDefinition;
import com.datastax.astra.client.tables.definition.columns.ColumnDefinitionVector;
import com.datastax.astra.client.tables.definition.columns.ColumnTypes;
import com.datastax.astra.client.tables.definition.rows.Row;

import static com.datastax.astra.client.core.query.Sort.ascending;
import static com.datastax.astra.client.core.vector.SimilarityMetric.COSINE;
import static java.time.Duration.ofSeconds;

public class DropTable {

 public static void main(String[] args) {
  // Database astraDb = new DataAPIClient(token).getDatabase(endpoint);
  Database db = DataAPIClients.localDbWithDefaultKeyspace();

  // Drop without options
  db.dropTable("games");

  // Adding a timestamp
  DropTableOptions options = new DropTableOptions()
   .ifExists(false)
   .timeout(ofSeconds(5));
  db.dropTable("games", options);
 }
}
curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/ASTRA_DB_KEYSPACE" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "dropTable": {
      "name": "TABLE_NAME"
  }
}'

Parameters:

Name Type Summary

dropTable

command

The Data API command to delete a table in a Serverless (Vector) database. It acts as a container for all the attributes and settings required to delete the table.

name

string

The name of the table to delete.

Returns:

A successful request returns 200 OK.

Example response
{
  "status": {
    "ok": 1
  }
}

Example:

curl -sS --location -X POST "ASTRA_DB_API_ENDPOINT/api/json/v1/default_keyspace" \
--header "Token: ASTRA_DB_APPLICATION_TOKEN" \
--header "Content-Type: application/json" \
--data '{
  "dropTable": {
    "name": "students"
  }
}'

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